/* ==========================================================================
   Genomain design tokens — ONE palette for every surface a user sees.
   Consumers: the WebOS shell (beta-webos-page, bundled by build.mjs), the
   public auth pages (application/frontend, imported from src/index.css) and
   Key Locker's hosted OAuth pages + Keycloak theme (copies made by
   design/sync-identity.sh — never edit the copies).

   Every value is what the SIGNED-IN shell actually renders — read with
   getComputedStyle on app.dev.genomainvault.com (Files, Settings, Team,
   Companies, the New-folder dialog, hover + focus states) on 2026-09-02,
   not lifted from a stylesheet. Black chrome, ivory canvas, warm-white
   cards, ONE teal (#2f9a8c) used as a signal: eyebrows, links, the focus
   outline, the active rail — never as a fill. Nothing here is new — do not
   add colours; change the shell first, then mirror it here. The shell's
   leftover neon cyan (#2fe3c4 / #38e8c8 / #5de3bd on the Settings tile, the
   Team pills, the dark New-folder dialog) is legacy, not palette — it is
   deliberately NOT here. See design/README.md.
   ========================================================================== */
:root {
  /* ---- chrome (dark): sidebar, top bar on phones, feature panels ---- */
  --gv-chrome-bg: #0e1114;                   /* .gvs-side */
  --gv-chrome-bg-2: #1b2024;                 /* avatar tile */
  --gv-chrome-bg-hover: #252a2e;             /* primary button :hover */
  --gv-chrome-tx: #f4f3ef;                   /* brand, active nav item */
  --gv-chrome-tx-2: #a7afb4;                 /* nav items, org line, group headings */
  --gv-chrome-line: rgba(255, 255, 255, .10);
  --gv-chrome-line-strong: rgba(255, 255, 255, .16);
  --gv-chrome-hover: rgba(255, 255, 255, .04);   /* nav item :hover */
  --gv-chrome-active: rgba(255, 255, 255, .06);  /* nav item .on */

  /* ---- canvas (light): the content area and everything on it ---- */
  --gv-bg: #f7f5f0;          /* ivory page + top bar (flat, no wash) */
  --gv-bg-2: #efece4;        /* secondary-button :hover, icon tiles */
  --gv-surface: #fffdf8;     /* card, input, search */
  --gv-surface-2: #e7e3da;   /* card :hover */
  --gv-line: rgba(22, 25, 28, .12);          /* card + input border */
  --gv-line-strong: rgba(22, 25, 28, .20);   /* secondary button + pill border, input :hover */
  --gv-line-hover: rgba(22, 25, 28, .30);    /* secondary button :hover */
  --gv-tx: #16191c;          /* ink */
  --gv-tx-2: #50565a;        /* secondary ink (7.4:1 on surface) */
  --gv-tx-3: #73797d;        /* tertiary ink — the shell's --tx-3 (4.3:1 on surface) */

  /* ---- signal ---- */
  --gv-teal: #2f9a8c;        /* eyebrows, links, focus outline, active rail, NEW badges */
  --gv-teal-deep: #0f6f64;   /* teal text on light where the shell uses it (kickers, info) */
  --gv-teal-wash: #e1eee9;   /* selected state fill (Settings nav .on) */
  --gv-teal-line: rgba(15, 111, 100, .16);   /* selected state border */
  /* The shell has no light-theme danger/ok/warn of its own (its --g-danger
     #ff6b6b is a dark-glass value that fails contrast on ivory), so these
     are the auth surface's — the only values not read from the app. */
  --gv-danger: #b91c1c;
  --gv-danger-bg: rgba(185, 28, 28, .08);
  --gv-danger-line: rgba(185, 28, 28, .40);
  --gv-ok: #15803d;
  --gv-ok-bg: rgba(21, 128, 61, .08);
  --gv-ok-line: rgba(21, 128, 61, .40);
  --gv-warn: #7a5a12;
  --gv-warn-bg: rgba(255, 197, 61, .18);
  --gv-warn-line: rgba(196, 138, 0, .55);

  /* ---- type (as rendered: Fraunces 400 headings / 500 brand, system sans UI) ---- */
  --gv-font-display: "Fraunces", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --gv-font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Inter, "Fira Sans", system-ui, sans-serif;
  --gv-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* ---- shape (as rendered) ---- */
  --gv-radius-card: 12px;    /* .set-card / Team cards (the shell's common card) */
  --gv-radius-panel: 12px;
  --gv-radius-control: 8px;  /* .vh-primary / .vh-secondary, nav items */
  --gv-radius-tile: 8px;     /* brand mark .gb-logo */
  --gv-radius-pill: 999px;   /* .set-pill is 20px on a 23px pill = fully round */

  /* ---- elevation (ink-tinted, never black glass) ---- */
  --gv-shadow-card: 0 1px 2px rgba(22, 25, 28, .06), 0 10px 26px rgba(22, 25, 28, .07), inset 0 1px rgba(255, 255, 255, .88);
  --gv-shadow-card-hover: 0 3px 6px rgba(22, 25, 28, .08), 0 16px 34px rgba(22, 25, 28, .12);
  --gv-shadow-btn: 0 7px 15px rgba(10, 12, 15, .18), inset 0 1px rgba(255, 255, 255, .12);
  --gv-shadow-btn-hover: 0 10px 20px rgba(10, 12, 15, .22), inset 0 1px rgba(255, 255, 255, .14);
  --gv-shadow-input: inset 0 1px 2px rgba(22, 25, 28, .06), 0 1px 0 rgba(255, 255, 255, .8);
  --gv-shadow-chrome: 10px 0 34px rgba(10, 12, 15, .20), inset -1px 0 rgba(255, 255, 255, .04);
  --gv-shadow-topbar: 0 8px 22px rgba(22, 25, 28, .055), inset 0 -1px rgba(22, 25, 28, .06);
  /* Focus = exactly the shell's `.gvs-shell :focus-visible { outline-color: teal }`
     on the UA's `outline: auto 1px`: a thin teal outline hugging the control,
     border and shadow untouched. No 3px ring, no border recolour. */
  --gv-focus-outline: auto 1px var(--gv-teal);
  --gv-scrim: rgba(4, 8, 12, .55);           /* modal backdrop (.os-modal) */

  /* ---- layout ---- */
  --gv-side-w: 236px;        /* brand column on desktop = the shell sidebar (.gvs-side) */
  --gv-topbar-h: 56px;       /* brand bar on phones = the shell's mobile bar */
  --gv-control-h: 44px;      /* every button/input clears the 44px tap target */
}

/* ==========================================================================
   Design 2027 — the material system (owner approved 2026-09-11, mockups
   memory/sessions/2026-09-11/design2027-mockups). ADDITIVE: every token above
   keeps its name and value; these are the new frosted-glass, elevation,
   radius, type-scale and motion tokens the shell frame reads. The accent
   stays --gv-teal; light mode stays white; dark = html[data-theme="dark"].
   ========================================================================== */
:root {
  /* ---- scene: the soft generated gradient behind the glass (CSS only) ---- */
  --gv-scene: radial-gradient(1100px 700px at 10% 0%, #d6e6e2 0%, transparent 55%),
              radial-gradient(900px 600px at 95% 15%, #efe6d6 0%, transparent 55%),
              radial-gradient(900px 500px at 55% 110%, #dcd3c6 0%, transparent 55%),
              linear-gradient(180deg, #ebe8e1 0%, #e1ddd4 60%, #d6d0c5 100%);
  /* ---- glass fills + the light 1px inner edge ---- */
  --gv-glass-panel: rgba(255, 253, 248, .66);      /* the large content panel */
  --gv-glass-panel-edge: rgba(255, 255, 255, .85);
  --gv-glass-bar: rgba(255, 253, 248, .55);        /* top bar, pill, dock */
  --gv-glass-bar-edge: rgba(255, 255, 255, .80);
  --gv-glass-card: rgba(255, 255, 255, .58);       /* borderless cards on the panel */
  --gv-glass-card-edge: rgba(255, 255, 255, .90);
  --gv-glass-card-hi: rgba(255, 255, 255, .95);    /* inset top highlight */
  --gv-glass-field: rgba(255, 255, 255, .72);
  --gv-glass-field-edge: rgba(22, 25, 28, .10);
  --gv-glass-sheet: rgba(255, 253, 248, .90);
  --gv-glass-on: rgba(22, 25, 28, .09);            /* selected pill item */
  --gv-glass-hover: rgba(22, 25, 28, .05);
  --gv-glass-scrim: rgba(4, 8, 12, .34);
  /* ---- blur radii ---- */
  --gv-blur-panel: blur(28px) saturate(1.3);
  --gv-blur-bar: blur(20px) saturate(1.2);
  --gv-blur-scrim: blur(4px);
  /* ---- elevation (soft, ink-tinted) ---- */
  --gv-elev-1: 0 1px 2px rgba(22, 25, 28, .05), 0 6px 18px rgba(22, 25, 28, .06);
  --gv-elev-2: 0 20px 50px rgba(22, 25, 28, .16), inset 0 1px rgba(255, 255, 255, .6);
  --gv-elev-3: 0 30px 80px rgba(22, 25, 28, .22), inset 0 1px rgba(255, 255, 255, .6);
  /* ---- 4. radii: ONE series, 8 / 12 / 16 / 24 / full — nothing between ---- */
  --gv-radius-8: 8px;
  --gv-radius-12: 12px;
  --gv-radius-16: 16px;
  --gv-radius-24: 24px;
  --gv-radius-full: 999px;
  --gv-radius-28: var(--gv-radius-24);   /* retired: 28 was off the series */
  /* =====================================================================
     THE MEASURE SYSTEM (design audit 2026-09-12; owner: "kolla så designen
     är matematiskt korrekt med storlek när det blir mindre och större").
     Every size a user sees comes from one of the five ladders below. A rule
     never writes a number — it reads a token. The test
     beta-webos-page/tests/design-2027-scale.test.mjs fails the build when a
     size outside these ladders appears in a 2027 stylesheet.

     1. TYPE — one modular scale. Base = 15 px (body, the SAME on a phone and
        on a 1920 desktop), ratio 1.200 (the minor third). Each rung is its
        neighbour × 1.2, rounded half-up to a whole pixel:
            s-2  11   s-1  13   s0  15   s1  18   s2  22
            s3   26   s4   31   s5  37   s6  44
        (13 = round(15 / 1.2), 11 = round(13 / 1.2), 18 = 15 × 1.2,
         22 = round(18 × 1.2), 26 = round(22 × 1.2), 31 = round(26 × 1.2),
         37 = round(31 × 1.2), 44 = round(37 × 1.2))
        Roles pick a rung, never a number:
            caption s-2 · footnote s-1 · callout s-1 · body s0 ·
            headline s0 (600 weight — HIG's Headline is body-sized) ·
            title-2 s0→s1 · title s1→s2 · title-1 s2→s3 ·
            large-title s2→s4 · figure-sm s2→s3 · figure s3→s5
        Two rungs that differed by 1 px (callout 14 vs footnote 13,
        headline 16 vs body 15) were below perception — they are one rung now.
     2. GROWING AND SHRINKING — continuous, never jumpy. A role with two rungs
        is clamp(min, intercept + k·vw, max): min is the rung at 390 px, max
        the rung at 1920 px, and the middle is linear in the window width, so
        nothing snaps at a breakpoint. k = 100 × (max − min) / 1530 and
        intercept = min − 390 × (max − min) / 1530.
     3. SPACE — multiples of 4 only: --gv-sp-1 … --gv-sp-12. 8 is the rhythm,
        4 the half step. No 6, no 10, no 14, no 18.
     4. SHAPE — one radius series: 8 / 12 / 16 / 24 / full. Nothing between.
     5. CONTROLS — --gv-ctl 36 → 40 px (continuous), --gv-ctl-sm 32 → 36,
        fields = --gv-ctl, and every control keeps a --gv-hit (44 px) touch
        target. Icons are 16 / 20 / 24.
     LINE HEIGHT — 1.2 for a heading or a label, 1.5 for prose, 1 only for a
     single glyph in a box. Nothing else.
     MOTION — 150 ms small state · 220 ms panel/sheet · 300 ms page;
     --gv-ease in, --gv-ease-out out, --gv-ease-spring for a press; rows
     stagger --gv-stagger (24 ms) up to --gv-stagger-max (8) rows; everything
     off under prefers-reduced-motion.
     ===================================================================== */
  /* ---- 1. the type ladder (the only sizes that exist) ---- */
  --gv-step-n2: 11px; --gv-step-n1: 13px; --gv-step-0: 15px; --gv-step-1: 18px;
  --gv-step-2: 22px; --gv-step-3: 26px; --gv-step-4: 31px; --gv-step-5: 37px; --gv-step-6: 44px;
  /* ---- the roles (clamped ones grow continuously from 390 to 1920 px) ---- */
  --gv-fs-caption: var(--gv-step-n2);                                 /* 11 */
  --gv-fs-footnote: var(--gv-step-n1);                                /* 13 */
  --gv-fs-callout: var(--gv-step-n1);                                 /* 13 (was 14 — same rung as footnote) */
  --gv-fs-body: var(--gv-step-0);                                     /* 15 on a phone and on a desktop */
  --gv-fs-headline: var(--gv-step-0);                                 /* 15 at 600 (was 16) */
  --gv-fs-title-2: clamp(15px, 14.235px + .196vw, 18px);              /* s0 → s1 */
  --gv-fs-title: clamp(18px, 16.980px + .261vw, 22px);                /* s1 → s2 */
  --gv-fs-title-1: clamp(22px, 20.980px + .261vw, 26px);              /* s2 → s3 */
  --gv-fs-large-title: clamp(22px, 19.706px + .588vw, 31px);          /* s2 → s4 */
  --gv-fs-figure-sm: clamp(22px, 20.980px + .261vw, 26px);            /* s2 → s3 (ERP secondary figures) */
  --gv-fs-figure: clamp(26px, 23.196px + .719vw, 37px);               /* s3 → s5 (ERP / KPI figures) */
  /* ---- line height: heading / prose / single glyph, nothing else ---- */
  --gv-lh-tight: 1.2;          /* every heading and every label */
  --gv-lh-body: 1.5;           /* everything that is read as prose */
  --gv-lh-flat: 1;             /* one glyph in a box — there is no line to balance */
  /* ---- the shorthands read the rungs and the two line heights ---- */
  --gv-type-large-title: 300 var(--gv-fs-large-title) / var(--gv-lh-tight) var(--gv-font-ui);
  --gv-type-title: 400 var(--gv-fs-title) / var(--gv-lh-tight) var(--gv-font-ui);
  --gv-type-title-2: 500 var(--gv-fs-title-2) / var(--gv-lh-tight) var(--gv-font-ui);
  --gv-type-headline: 600 var(--gv-fs-headline) / var(--gv-lh-tight) var(--gv-font-ui);
  --gv-type-body: 400 var(--gv-fs-body) / var(--gv-lh-body) var(--gv-font-ui);
  --gv-type-callout: 400 var(--gv-fs-callout) / var(--gv-lh-body) var(--gv-font-ui);
  --gv-type-footnote: 400 var(--gv-fs-footnote) / var(--gv-lh-body) var(--gv-font-ui);
  --gv-type-caption: 600 var(--gv-fs-caption) / var(--gv-lh-tight) var(--gv-font-ui);
  --gv-tracking-title: -.02em;
  /* ---- 3. space: multiples of 4, nothing else ---- */
  --gv-sp-1: 4px; --gv-sp-2: 8px; --gv-sp-3: 12px; --gv-sp-4: 16px; --gv-sp-5: 20px;
  --gv-sp-6: 24px; --gv-sp-7: 28px; --gv-sp-8: 32px; --gv-sp-9: 36px; --gv-sp-10: 40px;
  --gv-sp-11: 44px; --gv-sp-12: 48px;
  /* ---- 5. controls: --gv-ctl to the eye, --gv-hit to the finger ---- */
  --gv-ctl: clamp(36px, 34.980px + .261vw, 40px);   /* mic / send / "+" / top-bar circles / pill rows */
  --gv-ctl-sm: clamp(32px, 30.980px + .261vw, 36px);/* secondary rounds (segment buttons, chips) */
  --gv-hit: 44px;              /* the touch target every control keeps */
  --gv-field-h: var(--gv-ctl); /* inputs, selects, the "Sök eller fråga" pill */
  --gv-ic-sm: 16px;            /* icons: three sizes, all on the 4 grid */
  --gv-ic: 20px;
  --gv-ic-lg: 24px;
  --gv-card-pad: var(--gv-sp-4);          /* card inset (16; 12 on a phone) */
  --gv-card-pad-tight: var(--gv-sp-3);    /* dense cards, list rows (12; 8 on a phone) */
  /* ---- motion ---- */
  --gv-motion-fast: 150ms;
  --gv-motion-base: 220ms;
  --gv-motion-slow: 300ms;
  --gv-ease: cubic-bezier(.2, .8, .2, 1);        /* something arriving */
  --gv-ease-out: cubic-bezier(.4, 0, .2, 1);     /* something leaving */
  --gv-ease-spring: cubic-bezier(.34, 1.4, .4, 1);
  --gv-motion-loop: 1s;        /* a loader's one turn — a loop, not a state change */
  --gv-stagger: 24ms;          /* per row */
  --gv-stagger-max: 8;         /* rows that stagger; the rest share the last delay */
  /* ---- layout ---- */
  --gv-pill-w: 88px;          /* the floating navigation pill */
  --gv-pill-col: 124px;       /* the column the pill floats in */
  --gv-panel-gap: 16px;       /* panel inset from the window edge */
  /* ---- the switch and the status dot (list rows, 2026-09-14) ----
     ONE switch for every list row: the platform's own 51 × 31 with a 27 px
     knob inset 2 px (the size a thumb already knows), teal when on. A status
     dot is a glyph, not a box — 6 px, centred on the footnote's line — so it
     sits beside the words the way a bullet does, never as a badge. */
  --gv-switch-w: 51px;
  --gv-switch-h: 31px;
  --gv-switch-knob: 27px;
  --gv-switch-inset: 2px;
  --gv-dot: 6px;
}
html[data-theme="dark"] {
  --gv-scene: radial-gradient(1200px 700px at 15% 0%, #2f4650 0%, transparent 55%),
              radial-gradient(900px 600px at 95% 20%, #34424f 0%, transparent 55%),
              radial-gradient(800px 500px at 60% 110%, #4a3f36 0%, transparent 55%),
              linear-gradient(180deg, #1a2328 0%, #12181c 60%, #1c1a17 100%);
  --gv-glass-panel: rgba(20, 25, 30, .62);
  --gv-glass-panel-edge: rgba(255, 255, 255, .14);
  --gv-glass-bar: rgba(255, 255, 255, .08);
  --gv-glass-bar-edge: rgba(255, 255, 255, .14);
  --gv-glass-card: rgba(255, 255, 255, .07);
  --gv-glass-card-edge: rgba(255, 255, 255, .11);
  --gv-glass-card-hi: rgba(255, 255, 255, .12);
  --gv-glass-field: rgba(255, 255, 255, .08);
  --gv-glass-field-edge: rgba(255, 255, 255, .16);
  --gv-glass-sheet: rgba(28, 34, 40, .88);
  --gv-glass-on: rgba(255, 255, 255, .16);
  --gv-glass-hover: rgba(255, 255, 255, .08);
  --gv-glass-scrim: rgba(4, 8, 12, .50);
  --gv-elev-1: 0 1px 2px rgba(0, 0, 0, .18), 0 6px 18px rgba(0, 0, 0, .18);
  --gv-elev-2: 0 20px 50px rgba(0, 0, 0, .30), inset 0 1px rgba(255, 255, 255, .16);
  --gv-elev-3: 0 30px 80px rgba(0, 0, 0, .40), inset 0 1px rgba(255, 255, 255, .16);
  /* canvas + ink on dark glass: 13.5:1 / 8.6:1 / 5.6:1 on the panel */
  --gv-bg: #171d22;
  --gv-bg-2: #1e252b;
  --gv-surface: #202830;
  --gv-surface-2: #283139;
  --gv-tx: #f4f3ef;
  --gv-tx-2: #c9cdcf;
  --gv-tx-3: #a3a9ad;
  --gv-line: rgba(255, 255, 255, .10);
  --gv-line-strong: rgba(255, 255, 255, .18);
  --gv-teal: #4fbfae;         /* 6.9:1 on the dark panel */
  --gv-teal-deep: #7fd6c7;
  --gv-teal-wash: rgba(79, 191, 174, .16);
  --gv-teal-line: rgba(79, 191, 174, .30);
}
/* Phones (design audit 2026-09-12): the type and the controls no longer JUMP here —
   every one of them is a clamp() above, so 390 → 1920 px is one continuous line and
   this block only carries what is genuinely stepped: the card inset (space is on the
   4 grid, and a grid does not interpolate). Body stays 15 px at every width. */
@media (max-width: 480px) {
  :root {
    --gv-card-pad: var(--gv-sp-3);         /* 12 */
    --gv-card-pad-tight: var(--gv-sp-2);   /* 8 */
  }
}

/* Feedback (phase 3, 2026-09-12) — the one curve the three-duration system was
   missing. A LOOP is not a state change: a ring that turns has no beginning and
   no end to ease, so it turns at a constant rate. It lives here as a token so
   that no stylesheet writes the keyword itself. */
:root { --gv-ease-loop: linear; }
