/* ==========================================================================
   Buttons — Touch friendly, Sage-styled
   Extracted from main.css for modularity (v0.8.0)
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.625rem 1rem;
    font-size: var(--text-md);   /* 14px — the control rung; was 0.9rem */
    font-weight: 500;
    border: none;
    border-radius: var(--radius-pill, 100px);
    cursor: pointer;
    min-height: 44px;
    /* ⛔ A <button class="btn"> rendered in the browser's default face (Arial)
       while an <a class="btn"> rendered in Plus Jakarta Sans, on every page —
       buttons do not inherit font-family unless told to (mcp-connect-page-
       review.md, finding 7). */
    font-family: inherit;
    transition: background-color var(--transition-base, 0.2s ease),
        border-color var(--transition-base, 0.2s ease),
        color var(--transition-base, 0.2s ease),
        box-shadow var(--transition-base, 0.2s ease),
        transform 0.1s ease;
}

/* ⛔ A hidden button must be hidden. `.btn` sets `display: inline-flex`,
   which outranks the browser's own `[hidden] { display: none }` — so every
   `.btn` a template marked `hidden` still rendered. On the scan surface
   that put "Check it" on rows nobody had asked to read, and "Use this day"
   before a day was picked (docs/redesign/scan-flow-review.md, finding 2);
   onboarding-tour.css had to special-case the same trap. Once, here. */
.btn[hidden] {
    display: none;
}

/* SVG icons inside buttons inherit the button's text color.
   ⛔ **EXCEPT THE MARK, AND THIS RULE IS WHY THAT NEEDED SAYING** (2026-09-06).
   `.btn svg` is specificity (0,1,1) and `.btn__mark` is (0,1,0), so for as
   long as both existed the mark COULD NOT take a colour of its own — a
   `color:` on `.btn__mark` computed, resolved, and lost, silently. That looks
   exactly like a broken token, which is the wrong thing to go and investigate.
   The mark opts out by name and sets its own resting colour below; the
   handing-back is done there too, per state, rather than unconditionally
   here. */
.btn svg:not(.btn__mark),
.btn [aria-hidden="true"]>svg:not(.btn__mark) {
    color: inherit;
}

.btn:hover {
    filter: brightness(0.95);
}

/* ⛔ A disabled button must LOOK disabled. There was no rule for it, so a
   `disabled` primary painted exactly like a live one — on staging the deck's
   "Add to my journal" sat solid sage over "0 with a day you have confirmed"
   and read as a button that does nothing (Gabriel, 2026-09-02). */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    filter: none;
    transform: none;
}

.btn:active {
    transform: scale(0.98);
}

.btn-primary {
    background-color: var(--primary);
    color: var(--text-inverse);
}

.btn-primary:hover {
    background-color: var(--primary-dark);
    color: var(--text-inverse);
}

.btn-secondary {
    background-color: var(--background);
    color: var(--text-color);
    border: 1px solid var(--border-color);
}

.btn-secondary:hover {
    background-color: var(--background-hover);
}

.btn-sm {
    padding: 0.5rem 0.75rem;
    font-size: var(--text-sm);   /* 13px; was 0.8rem */
    min-height: 44px;
}

.btn-block {
    width: 100%;
}

.btn-outline {
    background: transparent;
    color: var(--primary);
    border: 1px solid var(--primary);
}

.btn-outline:hover {
    background: var(--primary);
    color: var(--text-inverse, #fff);
}

/* ⛔ OUTLINED, NOT FILLED — changed 2026-08-25 (Design 2.0, Batch 3).

   A filled red block is the loudest thing on any page it appears on, which
   made the irreversible path the visually obvious one on all four
   confirmation screens. Outlined still reads unmistakably as danger; it
   simply stops competing with the safe choice standing next to it.

   ⚠️ CHANGED HERE RATHER THAN AS A `--outline` MODIFIER ON FOUR SCREENS.
   `.btn-danger` has 14 call sites across 11 templates — Discard Draft, Revoke,
   Disable two-factor, three in the security tab. A modifier would have left
   the same button filled in seven places and outlined in four, which is worse
   than either. This is the house style for destructive actions now.

   It fills on hover, so the commitment still has a moment of weight to it. */
.btn-danger {
    background: transparent;
    color: var(--danger);
    border: var(--border-width-md) solid var(--danger);
}

.btn-danger:hover {
    background: var(--danger);
    color: var(--text-inverse);
}

.btn-success {
    background: var(--success-dark);
    color: var(--text-inverse);
    border: none;
}

.btn-success:hover {
    background: var(--success);
}

/* ⛔ Copy failed — and it stays failed. Not `.btn-danger`, which is the
   product's one signal for "this is gone"; the codes are still on the page
   and now selected. Security Batch 2, row 5.2 (audit H11). */
.btn-copy-failed {
    background: var(--warning-bg);
    color: var(--warning-text);
    border: var(--border-width) solid var(--warning-border);
    white-space: normal;
    text-align: left;
}

/* The off-screen textarea `execCommand("copy")` needs a selection in. */
.copy-scratch {
    position: fixed;
    top: 0;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
}

/* Edit/Delete action buttons */
.entry-actions,
.person-actions {
    display: flex;
    gap: 0.5rem;
    margin-top: 1rem;
}

.btn-edit,
.btn-delete {
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    min-height: 44px;
}

.btn-edit:hover {
    background: var(--primary-light);
    color: var(--primary);
}

.btn-delete:hover {
    background: var(--error-bg);
    color: var(--error);
}

/* Category pill styles moved to components/filters.css (.filter-pill) */
/* --------------------------------------------------------------------------
   Quiet — a real control that is not competing for the click (v0.79.13)

   ⭐ ADDED TO THE SYSTEM RATHER THAN HAND-ROLLED IN A PAGE. The Open Questions
   card needed "Not now" and "Never this subject" to be genuinely available but
   visually subordinate to the doors beside them — and the system had no such
   variant, so the first pass invented two one-off button styles inside
   open-questions.css. That is how the same pattern ends up written five
   different ways and a redesign has to touch five files.

   ⚠️ Quiet is NOT disabled and NOT a link. It keeps the 44px target from
   `.btn` (design_system.md:188, WCAG 2.5.5) and it keeps button semantics —
   only the paint recedes. §D: a control that collects a signal, implies an
   outcome and delivers none is worse than no control, and a control nobody can
   find is that failure with extra steps.
   -------------------------------------------------------------------------- */
.btn-quiet {
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid transparent;
}

.btn-quiet:hover,
.btn-quiet:focus-visible {
    background: var(--primary-light);
    color: var(--text-color);
}

/* --------------------------------------------------------------------------
   Pickable — a quiet ROW OF CHOICES, which is not the same thing as quiet.

   ⛔ **THESE TWO WERE ACCIDENTALLY IDENTICAL ON SCREEN AND IT SHIPPED.**
   `.btn-quiet-underline` was applied ALONGSIDE `.btn-quiet`, so it inherited
   `--text-secondary` and differed from a dismiss control by an underline
   alone. Measured on staging: the "That is true" reaction and the "Never this
   subject" mute rendered at the SAME 12.8px in the SAME rgb(171,180,163).

   ⚠️ That silently undid the whole point of the layout pass — "leave" was
   supposed to be quieter than "answer the question", and it was not.

   ⭐ THE DISTINCTION IS INTENT, NOT DECORATION:
     `.btn-quiet`            a DISMISSAL. Subordinate. --text-secondary.
     `.btn-quiet-pick`       a CHOICE we are asking her to make. Readable
                             (--text-color) and underlined so it reads as
                             pickable rather than as a label.

   ⛔ Use ONE of them, never both — combining them is what made them the same.
   -------------------------------------------------------------------------- */
.btn-quiet-pick {
    background: transparent;
    color: var(--text-color);
    border: 1px solid transparent;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: var(--border-color);
}

.btn-quiet-pick:hover,
.btn-quiet-pick:focus-visible {
    background: var(--primary-light);
    text-decoration-color: var(--primary);
}

/* ⭐ A BUTTON WITH ITS FEATURE'S MARK (2026-09-02). Ask carries Explore's
   mark, Write the Journal's, Not right? a pen, Forget the bin. The marks read
   at 16px (see the icon sheet in the Open Questions review). Used by the
   Open Questions rows and the Memory chips; declared once, here. */
.btn-with-mark {
    gap: var(--space-xs);
}

/* ⛔ **A 2px STROKE ON A 24px GRID DRAWS AT 1.33px WHEN YOU SCALE IT TO 16.**
   That is the whole of Gabriel's 2026-09-06 complaint — *"the say, handwrite
   and focus are like white and the others have shades of green"* — and it is
   arithmetic, not taste: a FILL does not thin when it is scaled, a STROKE
   does, so a line mark beside the nav's solid glyphs carries half the optical
   weight. `stroke-width` here is a CSS property, which beats the partial's own
   `stroke-width="2"` presentation attribute and inherits into every path, so
   the compensation is one declaration for all 96 line icons.
   ⚠️ 2.75 on the 24 grid = ~1.83px at 16px. Not 3 (a true 2px): these sit
   beside 14px text, and matching the label's weight is the goal, not beating
   it. */
.btn__mark {
    width: var(--icon-size-sm);
    height: var(--icon-size-sm);
    flex: none;
    stroke-width: 2.75;
    color: var(--icon-mark);
}

/* ⛔ **BUT THE MARK MUST STILL FOLLOW THE BUTTON.** This is the reason
   controls take the line family at all: on a filled primary the mark goes
   white with the label, and when the control is disabled it fades with it.
   `--icon-mark` is the resting colour on a quiet surface; anywhere the button
   sets its own foreground, the mark hands the decision back.
   ⚠️ A glyph or illustrative mark CANNOT do this — its tones are baked or
   token-bound — which is why `core/icons.py` allows only LINE in a control. */
.btn-primary .btn__mark,
.btn-danger .btn__mark,
.btn:disabled .btn__mark,
.btn[aria-pressed="true"] .btn__mark,
.btn-primary.btn__mark,
.btn-danger.btn__mark {
    color: inherit;
}

/* --------------------------------------------------------------------------
   Submitting
   --------------------------------------------------------------------------
   ⛔ **THIS WAS LIVE ON FIVE SCRIPTS AND PAINTED ON SEVEN PAGES.**
   `journal-home.js`, `entry-form.js`, `dashboard.js` and `relationship-form.js`
   all add `btn-loading` on submit, but the rule lived in `list-pages.css` —
   linked by seven templates, none of them the dashboard or the journal home.
   So on most of the app the class went on, the button stayed exactly as it
   was, and a second submit looked available. The sheet was retired on
   2026-09-05 and the rule came here, where `.btn` lives and every page loads
   it. `@keyframes spin` is in components/loading.css, also global.
   -------------------------------------------------------------------------- */
.btn-loading {
    position: relative;
    pointer-events: none;
    opacity: 0.75;
}

.btn-loading::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 12px;
    width: 16px;
    height: 16px;
    margin-top: -8px;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-top-color: #fff;
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
}
