/*
 * Stetworth /app — the composer surface: the form chrome and the
 * attach flow, cut from style.css's "Composer" and "Composer
 * attachments" sections with every declaration and comment unchanged
 * and in the original order.
 */
/*
 * Load order is load-bearing: the /app shell links every split sheet
 * BEFORE style.css.  That keeps both source-order contracts intact —
 * a rule kept behind in style.css still beats its shared group there
 * by file order, and the responsive tail at the end of style.css
 * still overrides this sheet's base rules at equal specificity.
 * This sheet declares no design-token block of its own and carries
 * no media block of any kind — every width, motion and paged
 * override for these rules lives in style.css's responsive tail
 * (docs/APP.md#the-split-stylesheets).
 */

/* ============================================================
 * Composer (Unit 3)
 *
 * The "New Task" composer card sits between the header and the gallery.
 * It is centered, capped to a comfortable reading width, and uses the
 * same surface treatment as the gallery cards so it reads as a
 * first-class member of the page rather than a separate widget.
 * ============================================================ */

.composer {
    max-width: 720px;
    margin: 0 auto var(--s-7);
    padding: 0 var(--s-3);
}

.composer-form {
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    padding: var(--s-5);
    background: var(--c-paper);
    border: 1px solid var(--c-rule);
    border-radius: var(--radius);
    transition: border-color var(--t-base), box-shadow var(--t-slow);
}

.composer-form:focus-within {
    border-color: var(--c-ink-faint);
    box-shadow: var(--sh-lift);
}

.composer-label {
    font-family: var(--font-accent);
    font-size: var(--fs-title);
    color: var(--c-ink);
    margin-bottom: var(--s-1);
}

.composer-textarea {
    width: 100%;
    min-height: 88px;
    resize: vertical;
    font-family: var(--font-body);
    font-size: var(--fs-base);
    line-height: 1.5;
    color: var(--c-ink);
    background: var(--c-paper);
    border: 1px solid var(--c-rule-strong);
    border-radius: var(--radius-sm);
    padding: var(--s-3) var(--s-4);
    box-shadow: var(--sh-well);
    transition: border-color var(--t-base);
}

.composer-textarea::placeholder {
    color: var(--c-ink-muted);
}

.composer-textarea:focus {
    outline: none;
    border-color: var(--c-burnished);
    box-shadow: var(--sh-well), var(--focus-ring);
}

.composer-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--s-3);
}

.composer-status {
    flex: 1;
    font-size: var(--fs-ui);
    color: var(--c-ink-muted);
    opacity: 0;
    transition: opacity var(--t-base);
}

.composer-status-visible { opacity: 1; }

/* The options disclosure
 * (docs/APP.md#the-composer-options-disclosure): the composer's
 * accessories — the attach block, the destination line, the
 * integration chips — folded behind one native <details> whose
 * summary line carries the facts ("Options — 2 files · 1 excluded ·
 * acme/ledger", a targeted textContent write by
 * _syncComposerOptionsLabel).  The working-set fold's quiet posture:
 * the platform's own marker is the affordance (no invented
 * chevrons), the summary takes the muted UI register over a hairline
 * rule, and nothing animates on the toggle in either direction —
 * nothing here to reconcile with the reduced-motion block.  The open
 * state is instance state restored by _wireComposerSection, never an
 * attribute stamped in markup. */
.composer-options {
    border-top: 1px solid var(--c-rule);
    padding-top: var(--s-2);
}

.composer-options-summary {
    font-size: var(--fs-ui);
    font-weight: 500;
    color: var(--c-ink-muted);
    cursor: pointer;
}

.composer-options-summary:hover {
    color: var(--c-ink);
}

summary.composer-options-summary:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* Open, the revealed blocks stand off the summary line.  The two
 * chip mounts carry their own margin-top; the attach block
 * (historically spaced by the form's own gap) takes the same step
 * from this rule. */
.composer-options[open] > .composer-options-summary {
    margin-bottom: var(--s-3);
}

/* ============================================================
 * Composer attachments (docs/APP.md#the-composer-attach-ui)
 *
 * The attach affordance sits between the textarea and the
 * integration chips: a pill Attach button (echoing the chip
 * silhouette), the one-task-only hint, then — once files are
 * staged — the removable file chips and the running-total meter.
 * Everything composes the existing tokens.  The drag treatment
 * paints the whole composer form as the drop target with the
 * burnished accent, since drops land anywhere on it; the chips'
 * transient states (uploading / removing) borrow the status
 * pills' pulse so "in flight" reads the same everywhere.
 * ============================================================ */

.composer-attach {
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
}

.composer-attach-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-3);
}

.composer-attach-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-body);
    font-size: var(--fs-ui);
    font-weight: 500;
    color: var(--c-ink-soft);
    background: var(--c-paper);
    border: 1px solid var(--c-rule-strong);
    border-radius: var(--radius-pill);
    padding: 0.28rem 0.8rem;
    cursor: pointer;
    transition: border-color var(--t-base), color var(--t-base);
}

.composer-attach-btn svg {
    width: 14px;
    height: 14px;
    flex: none;
}

.composer-attach-btn:hover {
    border-color: var(--c-ink);
    color: var(--c-ink);
}

.composer-attach-btn:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.composer-attach-btn:disabled {
    color: var(--c-ink-faint);
    border-color: var(--c-rule);
    cursor: default;
}

.composer-attach-hint {
    font-size: var(--fs-meta);
    color: var(--c-ink-muted);
}

.composer-attach-list {
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
}

.attach-chip-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-2);
}

/* A file chip: name (ellipsized, full name on the tooltip), size,
 * the textual state word for transient/stale chips, and the remove
 * control.  Soft-fill rounded rectangle — deliberately not the
 * integration toggles' pill, so files and toggles never read as one
 * control family. */
.attach-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    max-width: 100%;
    font-size: var(--fs-ui);
    color: var(--c-ink-soft);
    background: var(--c-paper-soft);
    border: 1px solid var(--c-rule-strong);
    border-radius: var(--radius-sm);
    padding: 0.22rem 0.3rem 0.22rem 0.7rem;
}

.attach-chip-name {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

.attach-chip-size {
    font-size: var(--fs-micro);
    color: var(--c-ink-muted);
    white-space: nowrap;
}

.attach-chip-state {
    color: var(--c-burnished-text);
    white-space: nowrap;
}

.attach-chip-uploading,
.attach-chip-removing {
    background: var(--c-paper);
    border-style: dashed;
}

.attach-chip-uploading .attach-chip-state,
.attach-chip-removing .attach-chip-state {
    animation: pill-pulse 1.6s ease-in-out infinite;
}

/* Stale chips: the session expired under them.  Dashed-and-faded
 * like an excluded integration chip, with the state word in the
 * failure accent — the words carry the state, never color alone. */
.attach-chip-stale {
    color: var(--c-ink-muted);
    background: transparent;
    border-style: dashed;
}

/* --c-ink-muted, not faint: the chip is still interactive while stale, so
   WCAG 1.4.3's inactive-component exception does not apply to its text.  The
   dashed border and the name color carry the stale state instead. */
.attach-chip-stale .attach-chip-size { color: var(--c-ink-muted); }

.attach-chip-stale .attach-chip-state {
    color: var(--c-status-failed);
    animation: none;
}

.attach-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex: none;
    font-size: var(--fs-body);
    line-height: 1;
    font-family: var(--font-body);
    color: var(--c-ink-muted);
    background: transparent;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: color var(--t-fast), background var(--t-fast);
}

.attach-chip-remove:hover {
    color: var(--c-status-failed);
    background: var(--c-paper);
}

.attach-chip-remove:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

.attach-chip-remove:disabled {
    color: var(--c-ink-faint);
    background: transparent;
    cursor: default;
}

/* Running session total against the server-reported cap: a slim
 * proportional track plus the text form of the same fact. */
.composer-attach-meter {
    display: flex;
    align-items: center;
    gap: var(--s-3);
}

.attach-meter-track {
    flex: none;
    width: 120px;
    height: 4px;
    border-radius: var(--radius-pill);
    background: var(--c-rule);
    overflow: hidden;
}

.attach-meter-fill {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--c-burnished);
    transition: width var(--t-base);
}

.attach-meter-text {
    font-size: var(--fs-meta);
    color: var(--c-ink-muted);
}

/* Drag-over: the whole composer form is the drop target, so the
 * form itself takes the invitation treatment — a drop-target
 * invitation, not focus, so its lighter 0.18 wash stays a literal
 * beside --focus-ring rather than joining the token. */
.composer-form-dragover {
    border-color: var(--c-burnished);
    border-style: dashed;
    box-shadow: 0 0 0 3px rgba(149, 115, 64, 0.18);
}

