/* ==========================================================================
   CaptivEYE Portal — semantic buttons
   ==========================================================================

   ONE definition of what a button looks like, so the meaning of a colour is
   the same on every page:

     .btn-save     white on blue    — commits a change
     .btn-edit     white on green   — opens something for editing
     .btn-delete   white on red     — destroys something
     .btn-add      white on orange  — creates something new / primary action
     .btn-alt      dark on aqua     — a secondary utility (duplicate, import,
                                      export, download): not destructive, not
                                      the primary action
     .btn-back     high contrast    — leaves without committing

   WHY THIS FILE EXISTS
   --------------------
   `.btn` was previously defined in sixteen places, eight of them byte-identical
   copies sitting in page-level <style> blocks. Because an inline block beats a
   linked stylesheet, those copies silently stripped `display:inline-flex` and
   `align-items:center` off v2-template.css's .btn-primary/-secondary/-danger.
   That is why icon-only buttons rode ~2px high: the button fell back to
   inline-block, so its .btn-icon span baseline-aligned instead of centring, and
   why one page carried a `.btn-simulate .btn-icon { transform: translateY(2px) }`
   magic-number patch for a single button.

   Pages adopting this file must DELETE their local .btn / .btn-primary /
   .btn-secondary / .btn-danger / .btn-sm copies, or nothing here applies.

   LOADING
   -------
   Linked per page with a ?v={filemtime} cache-bust, AFTER v2-template.css and
   BEFORE the page's own <style>. nginx serves /css/*.css with
   `expires 30d, immutable`, so an un-versioned link would go stale for a month
   after any edit — the reason so much CSS ended up inline in the first place.

   CONTRAST NOTE
   -------------
   Orange (3.07:1) and green (3.36:1 light / 2.17:1 dark) do not meet WCAG AA
   for white text; this was measured and kept deliberately, to preserve the
   brand colours. Blue, red, aqua and back all pass. If that is revisited,
   change only the tokens below — nothing else needs to move.
   ========================================================================== */

:root {
    /* Save — the only genuinely new colour in the set. */
    --btn-save-bg: #2563eb;
    --btn-save-bg-hover: #1d4ed8;
    --btn-save-fg: #ffffff;

    /* Edit / Delete / Add reuse the existing semantic tokens where a page
       defines them, so a site that has retuned --success or --danger keeps its
       own values. The literals are the fallback for pages that do not. */
    --btn-edit-bg: var(--success, #20a05b);
    --btn-edit-bg-hover: #1a8b4e;
    --btn-edit-fg: #ffffff;

    --btn-delete-bg: var(--danger, #cb3f3f);
    --btn-delete-bg-hover: #b23636;
    --btn-delete-fg: #ffffff;

    --btn-add-bg: var(--accent, #ef7015);
    --btn-add-bg-hover: var(--accent-strong, #d97706);
    --btn-add-fg: #ffffff;

    /* Secondary utility. Dark blue on aqua — 5.76:1. */
    --btn-alt-bg: #7fd8d8;
    --btn-alt-bg-hover: #6bcccc;
    --btn-alt-fg: #0f4c5c;

    /* Back — off-white in light mode. */
    --btn-back-bg: #f2f2f2;
    --btn-back-bg-hover: #e4e4e4;
    --btn-back-fg: #3a3a3a;
    --btn-back-border: rgba(0, 0, 0, 0.14);
}

html[data-theme="dark"] {
    --btn-edit-bg: var(--success, #2cc970);
    --btn-edit-bg-hover: #23b061;

    --btn-delete-bg: var(--danger, #e05757);
    --btn-delete-bg-hover: #c94a4a;

    --btn-add-bg-hover: var(--accent-strong, #f0a330);

    /* Back — white on black in dark mode. */
    --btn-back-bg: #141414;
    --btn-back-bg-hover: #232323;
    --btn-back-fg: #ffffff;
    --btn-back-border: rgba(255, 255, 255, 0.22);
}

/* --------------------------------------------------------------------------
   Base geometry — shared by every variant
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: 1px solid transparent;
    border-radius: 10px;
    padding: 10px 14px;
    font-family: var(--font-body);
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--ease, 220ms ease), border-color var(--ease, 220ms ease);
}

/* The `display: inline-flex` above is a class rule, and it OUTRANKS the browser's
   own `[hidden] { display: none }` — so `btn.hidden = true` sets the attribute,
   passes every assertion, and leaves the button sitting on screen anyway. That
   defect has now been found three times: the users modal, the Guardian video
   controls (patched locally in guardian-video.css) and the ENHANCE button on
   both the livestream and hi-res viewers. Fixed once here, for every .btn.

   !important because the rule it has to beat is a class selector on the same
   element, and callers reach for `hidden` expecting the attribute to mean what
   it says. */
.btn[hidden] {
    display: none !important;
}

.btn:disabled,
.btn[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}

.btn-sm {
    padding: 6px 10px;
    font-size: 0.86rem;
    border-radius: 8px;
}

/* Icon-only: the glyph IS the button, so let it fill the box rather than float
   in the middle of a label-sized pill.
                                                                    2em = 32px
   32px glyph + 6px padding each side + 1px border each side = 46px square. The
   padding is cut from the .btn default of 10px/14px precisely so the button
   stays at the 46px it already was — all the extra space goes to the icon
   instead of growing the control.

   Applies to the ACTION buttons that carry no label (modal save, camera form
   save). Row actions use .btn-sm and stay at 1em: they sit in a tight row where
   column position already says what they do, and scaling them would only make
   the row taller. */
.btn.is-icon-only {
    padding: 6px;
}

.btn.is-icon-only .btn-icon {
    width: 2em;
    height: 2em;
}

/* The centring that the page-level clones used to break. `display:block` on the
   svg is what takes it off the text baseline; align-items on the button is what
   puts it in the middle. Both are required — either alone leaves it ~2px out. */
.btn .btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1em;
    height: 1em;
    flex-shrink: 0;
    line-height: 0;
}

.btn .btn-icon svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* A FontAwesome glyph inside .btn-icon — the save icon is one. Unlike an svg it
   is text, so it does not stretch to the box; the box has to size it instead,
   and the line-height:0 above has to be undone or the glyph sits off-centre. */
.btn .btn-icon i.fa-solid,
.btn .btn-icon i.fa-regular,
.btn .btn-icon i.fa-brands {
    display: block;
    font-size: 1em;
    line-height: 1;
}

/* Icon-only buttons give the box 2em and expected the svg to fill it. A glyph
   at 1em would rattle around in there, so it is scaled to about the same
   optical size the filled svg had. */
.btn.is-icon-only .btn-icon i.fa-solid,
.btn.is-icon-only .btn-icon i.fa-regular,
.btn.is-icon-only .btn-icon i.fa-brands {
    font-size: 1.5em;
}

/* FontAwesome glyphs are text, so they need the same treatment. */
.btn > i.fa-solid,
.btn > i.fa-regular,
.btn > i.fa-brands {
    display: inline-flex;
    align-items: center;
    line-height: 1;
}

/* --------------------------------------------------------------------------
   Variants
   -------------------------------------------------------------------------- */
.btn-save {
    background: var(--btn-save-bg);
    border-color: var(--btn-save-bg);
    color: var(--btn-save-fg);
}
.btn-save:hover,
.btn-save:focus-visible {
    background: var(--btn-save-bg-hover);
    border-color: var(--btn-save-bg-hover);
    color: var(--btn-save-fg);
}

.btn-edit {
    background: var(--btn-edit-bg);
    border-color: var(--btn-edit-bg);
    color: var(--btn-edit-fg);
}
.btn-edit:hover,
.btn-edit:focus-visible {
    background: var(--btn-edit-bg-hover);
    border-color: var(--btn-edit-bg-hover);
    color: var(--btn-edit-fg);
}

.btn-delete {
    background: var(--btn-delete-bg);
    border-color: var(--btn-delete-bg);
    color: var(--btn-delete-fg);
}
.btn-delete:hover,
.btn-delete:focus-visible {
    background: var(--btn-delete-bg-hover);
    border-color: var(--btn-delete-bg-hover);
    color: var(--btn-delete-fg);
}

.btn-add {
    background: var(--btn-add-bg);
    border-color: var(--btn-add-bg);
    color: var(--btn-add-fg);
}
.btn-add:hover,
.btn-add:focus-visible {
    background: var(--btn-add-bg-hover);
    border-color: var(--btn-add-bg-hover);
    color: var(--btn-add-fg);
}

.btn-alt {
    background: var(--btn-alt-bg);
    border-color: var(--btn-alt-bg);
    color: var(--btn-alt-fg);
}
.btn-alt:hover,
.btn-alt:focus-visible {
    background: var(--btn-alt-bg-hover);
    border-color: var(--btn-alt-bg-hover);
    color: var(--btn-alt-fg);
}

.btn-back {
    background: var(--btn-back-bg);
    border-color: var(--btn-back-border);
    color: var(--btn-back-fg);
}
.btn-back:hover,
.btn-back:focus-visible {
    background: var(--btn-back-bg-hover);
    color: var(--btn-back-fg);
}

/* --------------------------------------------------------------------------
   Legacy aliases
   --------------------------------------------------------------------------
   .btn-primary / -secondary / -danger / -success are used in ~140 places. They
   are mapped here so a page can delete its local copies and land on the
   semantic colours rather than on v2-template.css's older values — its
   .btn-danger is a raw #ff0000, noticeably harsher than the --danger every page
   actually uses, so falling back to it would be a regression.

   Orange means "primary action", which is why Sort and Add share it. Use
   .btn-add on things that create, .btn-primary on everything else orange.
   -------------------------------------------------------------------------- */
.btn-primary {
    background: var(--btn-add-bg);
    border-color: var(--btn-add-bg);
    color: var(--btn-add-fg);
}
.btn-primary:hover,
.btn-primary:focus-visible {
    background: var(--btn-add-bg-hover);
    border-color: var(--btn-add-bg-hover);
    color: var(--btn-add-fg);
}

.btn-danger {
    background: var(--btn-delete-bg);
    border-color: var(--btn-delete-bg);
    color: var(--btn-delete-fg);
}
.btn-danger:hover,
.btn-danger:focus-visible {
    background: var(--btn-delete-bg-hover);
    border-color: var(--btn-delete-bg-hover);
    color: var(--btn-delete-fg);
}

.btn-success {
    background: var(--btn-edit-bg);
    border-color: var(--btn-edit-bg);
    color: var(--btn-edit-fg);
}
.btn-success:hover,
.btn-success:focus-visible {
    background: var(--btn-edit-bg-hover);
    border-color: var(--btn-edit-bg-hover);
    color: var(--btn-edit-fg);
}

/* Neutral. Uses the page's own surface tokens where they exist, so a page keeps
   its own panel colour instead of being forced to one grey. */
.btn-secondary {
    background: var(--surface-2, rgba(255, 255, 255, 0.08));
    border-color: var(--border, var(--frame-border, rgba(255, 255, 255, 0.14)));
    color: var(--text, var(--text-main, inherit));
}
.btn-secondary:hover,
.btn-secondary:focus-visible {
    background: color-mix(in srgb, var(--surface-2, rgba(255, 255, 255, 0.08)) 80%, var(--text, #888) 8%);
}

/* Keyboard focus has to survive the colour swap above. */
.btn:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent, #ef7015) 70%, #ffffff);
    outline-offset: 2px;
}
