/* Elshorafa Tools Hub, shared design system.
   TOKENS v3 (2026-08-03), wave 1 of the design upgrade spec.
   One paste repaints every page: every legacy token name below survives as an
   alias, so no page needs an edit to keep working. Outfit + Fira Code +
   Merriweather, loaded exactly as CONTRACT.md section 2 prints the link. */

:root{

/* --- NEUTRAL RAMP, the only greys in the product ------------------- */
--n-0:#ffffff;      /* was --card + --primary-foreground + 132 hardcoded #fff */
--n-50:#f9fafb;     /* was --muted */
--n-100:#f4f5f7;    /* was --input-bg */
--n-150:#f4f6f7;    /* page background. Amended from #e8ebed by owner decision
                       03 Aug so cards layer instead of box. This is the one
                       new hex in the ramp, CONTRACT.md section 2 updated. */
--n-200:#e5e7eb;    /* was --sidebar-border, 136 uses */
--n-300:#cccccc;    /* was --border, 137 uses, now demoted to 3 permitted places */
--n-400:#808080;    /* disabled text and the dashed pip edge */
--n-500:#6b7280;    /* was --muted-foreground, 32 uses */
--n-600:#4b5563;    /* was --text-2 */
--n-800:#333333;    /* was --foreground, retired to on-dark captions */
--n-900:#111827;    /* brand Deep Charcoal, was 10 hardcoded literals, now the ink */
--n-950:#1a1a1a;    /* was --ink plus 5 hardcoded literals */

/* --- SURFACES ------------------------------------------------------ */
--bg:var(--n-150);  --surface:var(--n-0);  --surface-2:var(--n-50);
--input-bg:var(--n-100);  --ink:var(--n-950);

/* --- BORDER, one hairline, in alpha so it sits on any fill ---------- */
--hairline:rgba(17,24,39,0.07);         /* replaces --border #cccccc, ~137 sites */
--hairline-strong:rgba(17,24,39,0.13);  /* permitted in EXACTLY 3 places, below */
/* the 3: table.hub thead th bottom, .input at rest, .hub-header once scrolled.
   Spinner tracks and the wizard step ring are FILLS, not hairlines: they take
   --n-200 from the ramp so the law stays at exactly three. */

/* --- TEXT, widened at both ends so headings stop needing weight 800 - */
--text-1:var(--n-900);   /* was --foreground #333333, now on brand ink */
--text-2:var(--n-600);
--text-3:var(--n-500);   /* was --muted-foreground, 185 uses */
--text-disabled:var(--n-400);
--on-dark:var(--n-0);

/* --- BRAND, unchanged values, one name each ------------------------ */
--teal:#2c687a;  --teal-deep:#245666;  --teal-soft:#eef4f6;
--teal-tint:#d9e8ec;  --teal-ink:#1d4854;
--terra:#df6035;      /* was TWO terracottas: --ring #e05d38 (the logo) and */
--terra-hover:#c4502a;/* --primary #df6035 (every CTA). Collapsed onto the CTA */
--terra-tint:#fbe9e2; /* value, so the mark and the button agree. */

/* --- VERDICT, plus the warn token that never existed ---------------- */
--good:#15803d;  --good-bg:#ecf7ef;
--warn:#a16207;  --warn-bg:#fbf1de;   /* was hardcoded 15x, bg improvised 4 ways */
--bad:#ef4444;   --bad-bg:#fdecec;
--bad-line:#f3c6c6;

/* --- TYPE, 9 steps replacing 41 --------------------------------------
   Map: 7 to 10.5 -> delete the element or --fs-micro
        11,11.5 -> --fs-micro | 12,12.5 -> --fs-xs | 13,13.5 -> --fs-sm
        14,14.5 -> --fs-body | 15,15.5,16,16.5 -> --fs-lead
        17,17.5,18,19 -> --fs-h3 | 20,21,22,23 -> --fs-h2
        24,25,26,27,28,30 -> --fs-h1 | 34,40,44,46,62,64 -> --fs-display
   Nothing renders below 11px anywhere in the product. */
--fs-display:clamp(32px,4.6vw,46px);  /* replaces all 15 one-off clamp() heads */
--fs-h1:30px;  --fs-h2:22px;  --fs-h3:17px;
--fs-lead:16px; --fs-body:15px; --fs-sm:13px; --fs-xs:12px; --fs-micro:11px;
--fs-num-sm:17px; --fs-num:21px; --fs-num-lg:26px; --fs-num-xl:32px; /* was 34 */
--lh-display:1.12; --lh-heading:1.30; --lh-ui:1.45; --lh-body:1.60;
--ls-display:-0.025em; --ls-heading:-0.01em; --ls-ui:0; --ls-label:0.08em;
--ls-mark:0.12em;  /* wordmark ONLY. 22 tracking values collapse to these 5 */
/* WEIGHTS: 400 body, 500 UI labels, 600 every heading and button label,
   700 the wordmark and KPI numerals only. 800 is retired (40 uses today);
   compensate at display size with --ls-display, not with weight. */

/* --- SPACING, 9 steps replacing 181 paddings and 23 gaps ------------
   Map: 1,2,3 -> --s-1 | 5,6,7 -> --s-2 | 9,10,11,13 -> --s-3
        14,15,18 -> --s-4 | 20,22,26 -> --s-5 | 28,30,34,36 -> --s-6
        40,42,44,46,52 -> --s-7 | 56,58,60,66 -> --s-8 | 72+ -> --s-9
   Only 2px and 6px survive outside the scale, and only INSIDE a control. */
--s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px;
--s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px;
--space-section:96px;        /* was 7 different rhythms across 6 pages */
--space-section-tight:56px;  /* supporting strips: clients, quotes, FAQ */
--space-card:24px;           /* was 5 values: 20, 22, 24, 26, 16 */

/* --- CONTROL METRICS, so .ui-dense never branches a component ------- */
--btn-py:10px; --btn-px:20px;
--btn-py-sm:7px; --btn-px-sm:14px;
--btn-py-lg:13px; --btn-px-lg:26px;
--ctl-h:44px; --ctl-px:14px;
--tab-py:8px; --tab-px:16px;
--chip-py:7px; --chip-px:16px;

/* --- RADIUS, 5 rungs replacing 19 -----------------------------------
   Map: 2,3,4,5 -> --r-xs | 6,7 -> --r-sm | 8,9,10,11 -> --r-md
        12,13,14 -> --r-lg | 16,18,20,26 -> --r-xl | 100,999 -> --r-full
   Nesting law: child radius = parent radius minus the padding between them. */
--r-xs:4px; --r-sm:6px; --r-md:8px; --r-lg:14px; --r-xl:18px; --r-full:999px;

/* --- ELEVATION, 4 levels replacing 66 shadows on 6 rgba bases -------
   ONE tint, rgba(17,24,39,x). e1 cards, panels, tiles. e2 popovers, menus,
   sticky bars. e3 modals and the hero frame. e4 is defined for completeness
   and assigned to nothing: nothing in the product sits above a modal.
   L1 on --bg carries NO border: the fill difference plus --e1 IS the edge.
   A surface nested INSIDE another surface separates with --hairline instead,
   never with a second shadow. Coloured shadows are banned, so the terracotta
   halo under the hero submit and the teal halo on .tab.on are both gone. */
--e1:0 1px 2px rgba(17,24,39,0.05);
--e2:0 1px 2px rgba(17,24,39,0.04), 0 12px 28px -8px rgba(17,24,39,0.10);
--e3:0 2px 6px rgba(17,24,39,0.06), 0 24px 56px -12px rgba(17,24,39,0.16);
--e4:0 8px 20px rgba(17,24,39,0.10), 0 40px 80px -16px rgba(17,24,39,0.22);
--sh-focus:0 0 0 3px var(--terra-tint);  /* the ONE surviving terracotta halo */
--sh-ring:0 0 0 3px var(--teal-tint);    /* the focus ring on inputs and picks */

/* --- MOTION, 4 durations and 3 curves replacing 31 declarations ------
   --dur-1 state change in place. --dur-2 enter and exit. --dur-3 large
   surface. --dur-data a number settling. Press is 60ms, always.
   MAY animate: opacity, transform, colour, border-color, box-shadow, and
   width only on elements 8px or less in that axis. NEVER: margin, padding,
   gap, grid-template, or filter on anything wider than a card. */
--dur-press:60ms; --dur-1:120ms; --dur-2:200ms; --dur-3:300ms; --dur-data:900ms;
--ease-out:cubic-bezier(0.22,0.61,0.36,1);
--ease-in:cubic-bezier(0.55,0.06,0.68,0.19);
--ease-data:cubic-bezier(0.16,1,0.3,1);
--lift:8px; --lift-toast:12px;  /* nothing in the product travels further */

/* --- LAYERS, 8 named replacing 17 unlayered integers ---------------- */
--z-base:1; --z-raised:10; --z-sticky:100; --z-drawer:200;
--z-scrim:300; --z-popover:400; --z-modal:500; --z-toast:600;

/* --- FONTS, exactly as the contract prints them --------------------- */
--font-sans:'Outfit',system-ui,sans-serif;
--font-mono:'Fira Code',ui-monospace,monospace;
--font-serif:'Merriweather',Georgia,serif;  /* one editorial accent word per page */

/* --- LEGACY ALIASES, delete only after the sweep is complete -------- */
--card:var(--surface); --muted:var(--surface-2); --background:var(--bg);
--foreground:var(--text-1); --text:var(--text-1);
--muted-foreground:var(--text-3);
--border:var(--hairline); --sidebar-border:var(--hairline);
--border-active:var(--hairline);   /* was #f0c4b3, a terracotta hover border */
--active-bg:var(--terra-tint);
--sidebar:var(--teal); --secondary:var(--teal); --toolbar:var(--teal);
--toolbar-2:var(--teal-deep); --toolbar-soft:var(--teal-soft);
--sidebar-rule:#23596a; --sidebar-foreground:var(--teal-soft);
--on-toolbar:var(--on-dark); --accent-soft:var(--teal-tint);
--accent-foreground:var(--teal-ink);
--primary:var(--terra); --terra-deep:var(--terra); --ring:var(--terra);
--primary-hover:var(--terra-hover); --destructive:var(--bad);
--radius:var(--r-md); --r-card:var(--r-lg); --r-bubble:18px; /* contract-named */
--shadow-card:var(--e1); --shadow-pop:var(--e3);
--mono:var(--font-mono); --sans:var(--font-sans);
--chart-1:#5f97a6;
/* DELETED, referenced zero times: --chart-2 --chart-3 --chart-4 --chart-5
   --sidebar-accent --sidebar-primary --sidebar-accent-foreground
   --primary-foreground */
}

/* DELETED: the .dark block. Nothing adds the class (no toggle, no
   prefers-color-scheme, no data-theme, no classList.add) and it could not work
   if something did: 132 hardcoded whites sit outside the ramp and three iframes
   render light user sites inside dark chrome. Dark mode is a project, not a
   block. Owner decision, 03 Aug 2026. */

/* .ui-dense overrides the SAME token names, so no component ever branches.
   These are the contract's own numbers (14 base, 13 secondary, 12 meta, h1 18). */
.ui-dense{
--fs-h1:18px; --fs-h2:15px; --fs-h3:14px; --fs-lead:14px;
--fs-body:14px; --fs-sm:13px; --fs-xs:12px;
--fs-num-lg:21px; --fs-num-xl:26px;
--space-card:16px; --space-section:48px;
--btn-py:8px; --btn-px:14px;
--btn-py-sm:6px; --btn-px-sm:11px;
--btn-py-lg:10px; --btn-px-lg:20px;
--ctl-h:34px; --ctl-px:12px;
--tab-py:6px; --tab-px:13px;
--chip-py:6px; --chip-px:12px;
line-height:var(--lh-ui); letter-spacing:-0.003em;
}

@media (max-width:760px){ :root{ --space-section:56px; --space-section-tight:40px; } }

/* ---------- Base ---------- */
*{ margin:0; padding:0; box-sizing:border-box; }
html{ scroll-behavior:smooth; }
body{
  font-family:var(--font-sans); background:var(--bg); color:var(--text-1);
  font-size:var(--fs-body); line-height:var(--lh-body); -webkit-font-smoothing:antialiased;
}
a{ cursor:pointer; }
button{ cursor:pointer; font-family:inherit; }
img{ max-width:100%; }
h1,h2,h3,h4{ font-weight:600; line-height:var(--lh-heading); letter-spacing:var(--ls-heading); }
h1{ font-size:var(--fs-h1); }
h2{ font-size:var(--fs-h2); }
h3{ font-size:var(--fs-h3); }
h4{ font-size:var(--fs-lead); }
.wrap{ max-width:1120px; margin:0 auto; padding:0 var(--s-5); }
.mono{ font-family:var(--font-mono); }
.serif{ font-family:var(--font-serif); font-weight:400; }  /* the one accent word */

/* ---------- FOCUS LAW ----------
   One ring, teal, 2px, offset 2px. On dark chrome it flips to white.
   Terracotta survives in focus only as the halo under .btn-primary. */
:focus-visible{ outline:2px solid var(--teal); outline-offset:2px; }
.side :focus-visible,
.toolbar :focus-visible,
.band-dark :focus-visible{ outline-color:var(--on-dark); }
.btn-primary:focus-visible{ box-shadow:var(--sh-focus); }
/* rail items live in a scroll container, so the ring goes inside the box */
.side :focus-visible,
.sitem:focus-visible,
.lib-rail :focus-visible{ outline-offset:-2px; }

/* ---------- Header ---------- */
.hub-header{
  background:var(--surface); border-bottom:1px solid var(--hairline);
  position:sticky; top:0; z-index:var(--z-sticky);
  transition:border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
/* HAIRLINE-STRONG, permitted place 1 of 3: the sticky header once scrolled */
.hub-header.scrolled, .hub-header[data-scrolled]{
  border-bottom-color:var(--hairline-strong); box-shadow:var(--e2);
}
.hub-nav{ max-width:1180px; margin:0 auto; padding:0 var(--s-5); height:60px; display:flex; align-items:center; gap:var(--s-5); }
.hub-brand{ display:flex; align-items:center; gap:var(--s-2); text-decoration:none; color:var(--text-1); }
.hub-mark{ width:24px; height:24px; background:var(--terra); border-radius:var(--r-sm); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.hub-brand b{ font-size:var(--fs-sm); font-weight:700; letter-spacing:var(--ls-mark); white-space:nowrap; }
.hub-brand span{ font-size:var(--fs-micro); color:var(--text-3); letter-spacing:var(--ls-label); }
.hub-links{ display:flex; gap:var(--s-5); }
.hub-links a{ font-size:var(--fs-sm); font-weight:500; color:var(--text-2); text-decoration:none; transition:color var(--dur-1) var(--ease-out); }
.hub-links a:hover, .hub-links a.active{ color:var(--teal); }
.hub-right{ margin-left:auto; display:flex; align-items:center; gap:var(--s-3); }

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--s-2);
  border:none; border-radius:var(--r-md);
  font-size:var(--fs-body); font-weight:600; line-height:var(--lh-ui);
  padding:var(--btn-py) var(--btn-px); text-decoration:none; position:relative;
  transition:background var(--dur-1) var(--ease-out),
             border-color var(--dur-1) var(--ease-out),
             color var(--dur-1) var(--ease-out),
             box-shadow var(--dur-1) var(--ease-out),
             transform var(--dur-press) var(--ease-out);
}
.btn-primary{ background:var(--terra); color:var(--on-dark); }
.btn-primary:hover{ background:var(--terra-hover); }
.btn-dark{ background:var(--teal); color:var(--on-dark); }
.btn-dark:hover{ background:var(--teal-deep); }        /* was opacity 0.9 */
.btn-line{ background:var(--surface); color:var(--text-1); border:1px solid var(--hairline); }
.btn-line:hover{ background:var(--surface-2); }        /* was a border-colour jump */
.btn-quiet{ background:transparent; color:var(--text-2); }
.btn-quiet:hover{ background:var(--surface-2); color:var(--text-1); }
.btn-lg{ padding:var(--btn-py-lg) var(--btn-px-lg); font-size:var(--fs-lead); }
.btn-sm{ padding:var(--btn-py-sm) var(--btn-px-sm); font-size:var(--fs-xs); }

/* the states that did not exist anywhere in the product before today */
.btn:active{ transform:translateY(1px); }
.btn[disabled], .btn[aria-disabled="true"], .btn.is-disabled{
  opacity:0.45; pointer-events:none; box-shadow:none;
}
.btn[data-loading]{ color:transparent; pointer-events:none; }
.btn[data-loading] > *{ opacity:0; }   /* width stays locked by the hidden label */
.btn[data-loading]::after{
  content:""; position:absolute; width:14px; height:14px; border-radius:var(--r-full);
  border:2px solid rgba(255,255,255,0.35); border-top-color:var(--on-dark);
  animation:hub-spin 0.8s linear infinite;
}
.btn-line[data-loading]::after, .btn-quiet[data-loading]::after{
  border-color:var(--n-200); border-top-color:var(--teal);
}
.chip:active, .tab:active, .pick:active,
.sitem:active, .icon-btn:active, .lib-card:active, .sc-tool:active,
a.card:active{ transform:translateY(1px); }

/* ---------- Footer ---------- */
.hub-footer{ border-top:1px solid var(--hairline); background:var(--surface); padding:var(--s-6) 0; margin-top:var(--s-9); }
.hub-foot{ max-width:1180px; margin:0 auto; padding:0 var(--s-5); display:flex; justify-content:space-between; align-items:center; font-size:var(--fs-xs); color:var(--text-3); flex-wrap:wrap; gap:var(--s-3); }
.hub-foot a{ color:var(--text-3); text-decoration:none; margin-left:var(--s-4); }
.hub-foot a:hover{ color:var(--text-1); }

/* ---------- Type ---------- */
.eyebrow{ font-size:var(--fs-xs); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--teal); }
h1.display{ font-size:var(--fs-display); font-weight:600; letter-spacing:var(--ls-display); line-height:var(--lh-display); }
h2.display{ font-size:var(--fs-h1); font-weight:600; letter-spacing:var(--ls-display); line-height:var(--lh-display); }
.lede{ color:var(--text-2); font-size:var(--fs-lead); line-height:var(--lh-body); max-width:620px; }
.accent{ color:var(--terra); }
.cap{ font-size:var(--fs-xs); color:var(--text-3); line-height:var(--lh-ui); }
.num{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; font-weight:600; }

/* ---------- Cards ----------
   ELEVATION LAW: an L1 surface sitting on --bg carries no border. The fill
   difference plus --e1 is the whole separation. Nested surfaces use --hairline. */
.card{
  background:var(--surface); border:none; border-radius:var(--r-lg);
  padding:var(--space-card); box-shadow:var(--e1);
  transition:transform var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out);
}
a.card{ display:block; text-decoration:none; color:var(--text-1); }
a.card:hover, .card-hover:hover{ transform:translateY(-2px); box-shadow:var(--e2); }
.card h3{ font-size:var(--fs-lead); font-weight:600; letter-spacing:var(--ls-heading); }
.card p{ font-size:var(--fs-sm); color:var(--text-2); }
.card-flat{ box-shadow:none; border:1px solid var(--hairline); }
.card-quiet{ background:var(--surface-2); box-shadow:none; border:1px solid var(--hairline); }
.card-flush{ padding:0; overflow:hidden; }
/* legacy: the stripe is retired, the class stays so old markup keeps working */
.card-top3{ border-top:1px solid var(--hairline); }

/* ---------- Toolbars (the teal chrome) ---------- */
.toolbar{ background:var(--teal); color:var(--on-dark); display:flex; align-items:center; gap:var(--s-3); padding:var(--s-3) var(--s-4); }
.toolbar .t-title{ font-size:var(--fs-sm); font-weight:600; letter-spacing:var(--ls-heading); }
.toolbar .t-sub{ font-size:var(--fs-xs); color:rgba(255,255,255,0.74); }
.toolbar .spacer{ margin-left:auto; }
.toolbar .btn-line{ background:rgba(255,255,255,0.10); color:var(--on-dark); border-color:rgba(255,255,255,0.24); }
.toolbar .btn-line:hover{ background:rgba(255,255,255,0.18); border-color:rgba(255,255,255,0.40); }
.toolbar .mono{ color:rgba(255,255,255,0.9); }
.toolbar-soft{ background:var(--teal-soft); border-bottom:1px solid var(--hairline); }
/* a sticky bar is elevation 2 */
.toolbar.is-sticky, .toolbar-soft.is-sticky{ position:sticky; top:0; z-index:var(--z-sticky); box-shadow:var(--e2); }

/* ---------- Chat bubbles (Apple and WhatsApp register) ---------- */
.bubble{ max-width:78%; padding:var(--s-3) var(--s-4); border-radius:var(--r-bubble); font-size:var(--fs-sm); line-height:var(--lh-ui); box-shadow:var(--e1); word-wrap:break-word; }
.bubble-me{ background:var(--teal); color:var(--on-dark); margin-left:auto; border-bottom-right-radius:var(--r-sm); }
.bubble-ai{ background:var(--surface); color:var(--text-1); border:1px solid var(--hairline); border-bottom-left-radius:var(--r-sm); }
.bubble-note{ background:var(--surface-2); color:var(--text-3); font-size:var(--fs-xs); border-radius:var(--r-lg); margin:0 auto; text-align:center; max-width:90%; box-shadow:none; }
.bubble-bad{ background:var(--bad-bg); color:var(--bad); border:1px solid var(--bad-line); border-bottom-left-radius:var(--r-sm); }
.bubble-row{ display:flex; margin-bottom:var(--s-3); }
.icon-tile{ width:38px; height:38px; border-radius:var(--r-md); background:var(--terra-tint); display:flex; align-items:center; justify-content:center; flex-shrink:0; }

/* ---------- Badges and chips ---------- */
.badge{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; padding:var(--s-1) var(--s-2); border-radius:var(--r-xs); white-space:nowrap; display:inline-block; }
.badge-free{ color:var(--good); background:var(--good-bg); }
.badge-pro{ color:var(--terra); background:var(--terra-tint); }
.badge-soon{ color:var(--text-3); background:var(--surface-2); border:1px solid var(--hairline); }
.chip{
  font-size:var(--fs-sm); font-weight:500; padding:var(--chip-py) var(--chip-px);
  border-radius:var(--r-md); border:1px solid var(--hairline);
  color:var(--text-2); background:var(--surface);
  transition:background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out),
             border-color var(--dur-1) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.chip:hover{ background:var(--surface-2); color:var(--text-1); }
/* COLOUR LAW: selection is chrome, so it is teal. Terracotta is action only. */
.chip.on{ background:var(--teal); border-color:var(--teal); color:var(--on-dark); }

/* ---------- Forms ---------- */
.field label{ display:block; font-size:var(--fs-sm); font-weight:500; margin-bottom:var(--s-2); }
.field .hint{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-1); }
.input, .select, textarea.input{
  width:100%; height:var(--ctl-h);
  /* HAIRLINE-STRONG, permitted place 2 of 3: an input at rest */
  border:1px solid var(--hairline-strong); border-radius:var(--r-md);
  padding:0 var(--ctl-px); font-size:var(--fs-body); font-family:inherit;
  color:var(--text-1); background:var(--input-bg); outline:none;
  transition:border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out);
}
textarea.input{ height:auto; padding:var(--s-3) var(--ctl-px); resize:vertical; line-height:var(--lh-ui); }
.input:hover, .select:hover, textarea.input:hover{ background:var(--surface); }
.input:focus, .select:focus, textarea.input:focus{
  border-color:var(--teal); background:var(--surface); box-shadow:var(--sh-ring);
}
.input[disabled], .select[disabled], textarea.input[disabled]{ opacity:0.45; pointer-events:none; }
.input.mono{ font-family:var(--font-mono); font-size:var(--fs-sm); }
.input::placeholder, textarea.input::placeholder{ color:var(--text-disabled); }

/* ---------- Tool page scaffold ---------- */
.tool-head{ padding:var(--s-7) 0 var(--s-5); }
.tool-head h1{ font-size:var(--fs-display); font-weight:600; letter-spacing:var(--ls-display); line-height:var(--lh-display); display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap; }
.tool-head p{ color:var(--text-2); font-size:var(--fs-lead); max-width:620px; margin-top:var(--s-2); }
.tool-panel{ background:var(--surface); border:none; border-radius:var(--r-lg); padding:var(--space-card); box-shadow:var(--e1); }
.tool-grid2{ display:grid; grid-template-columns:1fr 1fr; gap:var(--s-4); }
.result-tile{ background:var(--surface-2); border:1px solid var(--hairline); border-radius:var(--r-md); padding:var(--s-4); }
.result-tile .lbl{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--text-3); }
.result-tile .val{ font-family:var(--font-mono); font-size:var(--fs-num-lg); font-weight:700; margin-top:var(--s-1); font-variant-numeric:tabular-nums; }
.result-tile .val.good{ color:var(--good); }
.result-tile .val.warn{ color:var(--warn); }
.result-tile .val.bad{ color:var(--bad); }
.copy-row{ display:flex; gap:var(--s-3); align-items:center; }
.copy-row .input{ flex:1; }

/* ---------- Tables ---------- */
.panel{ background:var(--surface); border:none; border-radius:var(--r-lg); box-shadow:var(--e1); overflow-x:auto; }
table.hub{ width:100%; border-collapse:collapse; min-width:560px; }
/* HAIRLINE-STRONG, permitted place 3 of 3: the table head rule, now 1px */
table.hub thead th{ text-align:left; font-size:var(--fs-xs); font-weight:600; color:var(--text-1); background:var(--surface); padding:var(--s-3) var(--s-4); border-bottom:1px solid var(--hairline-strong); white-space:nowrap; }
table.hub tbody td{ padding:var(--s-3) var(--s-4); border-bottom:1px solid var(--hairline); font-size:var(--fs-sm); }
table.hub tbody tr:last-child td{ border-bottom:none; }

/* ---------- Wizard (builder) ---------- */
.wiz-steps{ display:flex; gap:var(--s-2); margin:var(--s-5) 0 var(--s-6); flex-wrap:wrap; }
.wiz-step{ display:flex; align-items:center; gap:var(--s-2); font-size:var(--fs-xs); font-weight:500; color:var(--text-3); padding:var(--s-2) var(--s-3); border-radius:var(--r-full); }
.wiz-step .n{ font-family:var(--font-mono); font-size:var(--fs-micro); width:20px; height:20px; border:1.5px solid var(--n-200); border-radius:var(--r-full); display:inline-flex; align-items:center; justify-content:center; }
.wiz-step.on{ color:var(--text-1); }
/* COLOUR LAW: progress is chrome, so the active step is teal */
.wiz-step.on .n{ background:var(--teal); border-color:var(--teal); color:var(--on-dark); }
.wiz-step.done .n{ background:var(--good-bg); border-color:var(--good); color:var(--good); }
.pick-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-3); }
.pick{
  border:1px solid var(--hairline); border-radius:var(--r-md); background:var(--surface);
  padding:var(--s-4); cursor:pointer; text-align:left; position:relative; box-shadow:var(--e1);
  transition:border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.pick:hover{ box-shadow:var(--e2); }
.pick.on{ border-color:var(--teal); box-shadow:var(--sh-ring); }
.pick b{ display:block; font-size:var(--fs-body); font-weight:600; }
.pick span{ font-size:var(--fs-xs); color:var(--text-3); }
.pick .tick{ position:absolute; top:var(--s-3); right:var(--s-3); width:18px; height:18px; border-radius:var(--r-full); background:var(--teal); display:none; align-items:center; justify-content:center; }
.pick.on .tick{ display:flex; }

/* ---------- Tabs (active = teal, the chrome colour) ---------- */
.tabbar{ display:inline-flex; gap:var(--s-1); background:var(--surface-2); border:1px solid var(--hairline); border-radius:var(--r-md); padding:var(--s-1); }
.tab{
  display:inline-flex; align-items:center; gap:var(--s-2); border:none; background:transparent;
  color:var(--text-3); font-size:var(--fs-sm); font-weight:500;
  padding:var(--tab-py) var(--tab-px); border-radius:var(--r-sm);
  transition:background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out), transform var(--dur-press) var(--ease-out);
}
.tab:hover{ color:var(--text-1); background:var(--surface); }
.tab.on{ background:var(--teal); color:var(--on-dark); }   /* the teal glow is deleted */

/* ---------- Dark band ---------- */
.band-dark{ background:var(--teal-deep); border-radius:var(--r-lg); color:var(--on-dark); padding:var(--s-7); }
.band-dark h2{ color:var(--on-dark); }
.band-dark .muted{ color:rgba(255,255,255,0.72); }

/* =====================================================================
   THE SIGNATURE: the pair of score rings.
   One component, five sizes, identical markup. Markup is exactly:
   <svg class="ring" viewBox="0 0 120 120">
     <circle cx="60" cy="60" r="52" fill="none" stroke="var(--hairline)" stroke-width="8"/>
     <circle class="ring-v" cx="60" cy="60" r="52" fill="none" stroke="var(--dc)"
             stroke-width="8" stroke-linecap="round" stroke-dasharray="326.73"
             stroke-dashoffset="326.73" transform="rotate(-90 60 60)"/>
   </svg>
   326.73 is 2 pi r at r 52. The track never changes colour, only --dc carries
   the verdict, and --dc is set BEFORE the first frame so the arc never changes
   colour mid sweep. Round caps, never a conic-gradient.
   ===================================================================== */
.ring{ display:block; width:var(--ring-size,138px); height:var(--ring-size,138px); flex-shrink:0; }
.ring circle{ stroke-width:var(--ring-w,8); }
.ring .ring-v{
  stroke:var(--dc,var(--teal));
  stroke-dasharray:326.73;
  stroke-dashoffset:calc(326.73 - 326.73 * var(--p,0) / 100);
  transition:stroke-dashoffset var(--dur-data) var(--ease-data);
}
.ring-report{ --ring-size:138px; --ring-w:8; }   /* the report header */
.ring-og{     --ring-size:120px; --ring-w:8; }   /* the 1200x630 og image */
.ring-app{    --ring-size:104px; --ring-w:6; }   /* the workspace project card */
.ring-geo{    --ring-size:96px;  --ring-w:6; }   /* the GEO checker result */
.ring-crop{   --ring-size:78px;  --ring-w:5; }   /* the landing hero crop */

.ring-wrap{ position:relative; display:grid; place-items:center; }
.ring-num{
  position:absolute; font-family:var(--font-mono); font-weight:700;
  font-size:var(--fs-num-xl); line-height:1; font-variant-numeric:tabular-nums;
  color:var(--text-1); text-align:center;
}
.ring-num small{ display:block; font-size:var(--fs-micro); font-weight:400; color:var(--text-3); margin-top:var(--s-1); }
.ring-app .ring-num, .ring-geo .ring-num{ font-size:var(--fs-num-lg); }
.ring-crop .ring-num{ font-size:var(--fs-num); }

.scorepair{ display:flex; align-items:flex-start; gap:var(--s-7); flex-wrap:wrap; }
.scoreone{ display:flex; flex-direction:column; align-items:center; gap:var(--s-3); min-width:0; }
.scoreone .sp-lab{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--text-3); }

/* the four answer-engine pips. A dashed pip is a measurement that did not
   happen, which the honesty contract requires us to show rather than fill. */
.pips{ display:flex; gap:var(--s-2); align-items:center; justify-content:center; }
.pip{ width:9px; height:9px; border-radius:var(--r-full); background:var(--n-200); border:1px solid transparent; flex-shrink:0; }
.pip-allowed{ background:var(--good); }
.pip-blocked{ background:var(--bad); }
.pip-unknown{ background:none; border:1px dashed var(--n-400); }
.pips-cap{ font-family:var(--font-mono); font-size:var(--fs-micro); color:var(--text-3); text-align:center; letter-spacing:0; }

/* =====================================================================
   SHARED COMPONENTS, authored once here so waves 2 to 5 only delete copies.
   ===================================================================== */

/* the measured row: a key, the value as it came back, a verdict colour */
.meas{ margin-top:var(--s-2); }
.meas-row{ display:flex; justify-content:space-between; gap:var(--s-3); align-items:baseline; padding:var(--s-2) 0; border-bottom:1px solid var(--hairline); font-size:var(--fs-xs); }
.meas-row:last-child{ border-bottom:none; }
.meas-row .k{ color:var(--text-2); }
.meas-row .v{ font-family:var(--font-mono); font-size:var(--fs-micro); text-align:right; word-break:break-word; color:var(--text-1); }
.meas-row .v.good{ color:var(--good); }
.meas-row .v.warn{ color:var(--warn); }
.meas-row .v.bad{ color:var(--bad); }
.meas-row .v.mute{ color:var(--text-3); }

/* the popover and menu surface, elevation 2 */
.pop{
  position:absolute; z-index:var(--z-popover); min-width:220px;
  background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-lg);
  box-shadow:var(--e2); padding:var(--s-2); overflow:hidden;
  opacity:0; transform:translateY(calc(var(--lift) * -0.5)); pointer-events:none;
  transition:opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.pop.on{ opacity:1; transform:translateY(0); pointer-events:auto; }
.pop-label{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--text-3); padding:var(--s-2) var(--s-3) var(--s-1); }
.pop-row{
  display:flex; align-items:flex-start; gap:var(--s-3); width:100%; text-align:left;
  padding:var(--s-2) var(--s-3); border-radius:var(--r-sm); border:none; background:none;
  color:var(--text-1); font-size:var(--fs-sm); font-weight:500; text-decoration:none;
  transition:background var(--dur-1) var(--ease-out);
}
.pop-row:hover, .pop-row:focus-visible{ background:var(--surface-2); }
.pop-row .ic{ color:var(--text-3); margin-top:2px; }
.pop-row:hover .ic{ color:var(--teal); }
.pop-row span{ display:block; font-size:var(--fs-xs); font-weight:400; color:var(--text-3); }
.pop-sep{ height:1px; background:var(--hairline); margin:var(--s-2) 0; }

/* the one empty state. No dashed borders anywhere in the product. */
.empty-state{ text-align:center; padding:var(--s-7) var(--s-5); background:var(--surface-2); border-radius:var(--r-lg); }
.empty-state .ic, .empty-state .es-ic{ color:var(--text-3); margin-bottom:var(--s-3); }
.empty-state b{ display:block; font-size:var(--fs-body); font-weight:600; color:var(--text-1); }
.empty-state p{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-2); max-width:44ch; margin-left:auto; margin-right:auto; line-height:var(--lh-ui); }
.empty-state .btn{ margin-top:var(--s-4); }

/* the gate. Never hide value silently: name what is behind it, one CTA. */
.gate{ position:relative; }
.gate-blur{ filter:blur(5px); pointer-events:none; user-select:none; opacity:0.55; }
.gate-card{
  display:flex; gap:var(--s-4); align-items:flex-start;
  background:var(--surface-2); border:1px solid var(--hairline); border-radius:var(--r-lg);
  padding:var(--s-4) var(--s-5); margin-top:var(--s-4);
}
.gate-card .gate-ic{ width:30px; height:30px; border-radius:var(--r-md); background:var(--surface); border:1px solid var(--hairline); color:var(--teal); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.gate-card b{ display:block; font-size:var(--fs-body); font-weight:600; }
.gate-card p{ font-size:var(--fs-xs); color:var(--text-2); margin-top:var(--s-1); line-height:var(--lh-ui); }
.gate-card .gate-cta{ margin-top:var(--s-3); display:flex; gap:var(--s-3); align-items:center; flex-wrap:wrap; }
.gate-card .gate-note{ font-size:var(--fs-micro); color:var(--text-3); }

/* the one toast. Bottom centre, class driven, role=status aria-live=polite. */
.toast{
  position:fixed; left:50%; bottom:var(--s-5); z-index:var(--z-toast);
  max-width:min(92vw,420px); padding:var(--s-3) var(--s-4);
  background:var(--ink); color:var(--on-dark); border-radius:var(--r-md);
  font-size:var(--fs-sm); line-height:var(--lh-ui); box-shadow:var(--e3);
  opacity:0; transform:translateX(-50%) translateY(var(--lift-toast)); pointer-events:none;
  transition:opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.toast.on{ opacity:1; transform:translateX(-50%) translateY(0); }
.toast-good{ background:var(--good); }
.toast-bad{ background:var(--bad); }

/* the skeleton, a left to right shimmer, and the spinner, always teal */
.skel{
  border-radius:var(--r-xs); background:var(--surface-2);
  background-image:linear-gradient(90deg,transparent 0%,rgba(255,255,255,0.85) 50%,transparent 100%);
  background-size:200% 100%; background-repeat:no-repeat;
  animation:hub-shimmer 1.4s var(--ease-out) infinite;
}
.skel-line{ height:11px; margin-bottom:var(--s-2); }
.skel-line:last-child{ width:60%; margin-bottom:0; }
@keyframes hub-shimmer{ 0%{ background-position:-100% 0; } 100%{ background-position:200% 0; } }
.spin{
  width:14px; height:14px; flex-shrink:0; border-radius:var(--r-full);
  border:2px solid var(--n-200); border-top-color:var(--teal);
  animation:hub-spin 0.8s linear infinite;
}
.spin-lg{ width:22px; height:22px; border-width:2.5px; }
@keyframes hub-spin{ to{ transform:rotate(360deg); } }

/* the callout and the raw output block */
.callout{ display:flex; gap:var(--s-3); align-items:flex-start; background:var(--surface-2); border-radius:var(--r-md); padding:var(--s-3) var(--s-4); font-size:var(--fs-xs); color:var(--text-2); line-height:var(--lh-ui); }
.callout .ic{ color:var(--teal); margin-top:2px; }
.callout-good{ background:var(--good-bg); color:var(--good); }
.callout-warn{ background:var(--warn-bg); color:var(--warn); }
.callout-bad{ background:var(--bad-bg); color:var(--bad); }
.code-out{
  font-family:var(--font-mono); font-size:var(--fs-xs); line-height:var(--lh-ui);
  background:var(--ink); color:var(--teal-soft); border-radius:var(--r-md);
  padding:var(--s-3) var(--s-4); overflow-x:auto; white-space:pre; tab-size:2;
}

/* the KPI tile set. --tile-cols drives the grid, so no page redefines it. */
.tiles{ display:grid; grid-template-columns:repeat(var(--tile-cols,4),minmax(0,1fr)); gap:var(--s-3); margin-top:var(--s-3); }
.tile{ background:var(--surface-2); border-radius:var(--r-md); padding:var(--s-3) var(--s-4); min-width:0; }
.tile .lbl{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--text-3); }
.tile .val{ font-family:var(--font-mono); font-size:var(--fs-num); font-weight:700; margin-top:var(--s-1); font-variant-numeric:tabular-nums; }
.tile .val small{ font-size:var(--fs-micro); color:var(--text-3); font-weight:400; }
.tile .val.good{ color:var(--good); }
.tile .val.warn{ color:var(--warn); }
.tile .val.bad{ color:var(--bad); }
.tile .cap{ font-size:var(--fs-micro); color:var(--text-3); margin-top:var(--s-1); line-height:var(--lh-ui); }
/* inside a card the tile drops its fill and separates with a rule instead */
.card .tiles, .tool-panel .tiles{ gap:0; }
.card .tile, .tool-panel .tile{ background:none; padding:var(--s-2) var(--s-4); border-left:1px solid var(--hairline); }
.card .tile:first-child, .tool-panel .tile:first-child{ border-left:none; padding-left:0; }

/* ONE verdict vocabulary across the whole product: PASS WARN FIX SKIP */
.st{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; padding:var(--s-1) var(--s-2); border-radius:var(--r-xs); white-space:nowrap; flex-shrink:0; display:inline-block; text-align:center; min-width:54px; }
.st-pass{ color:var(--good); background:var(--good-bg); }
.st-warn{ color:var(--warn); background:var(--warn-bg); }
.st-fix{ color:var(--bad); background:var(--bad-bg); }
.st-skip{ color:var(--text-3); background:var(--surface-2); }

/* the build-state chip, capped at one per surface, replacing 34 apologies */
.state{ display:inline-flex; align-items:center; gap:var(--s-2); font-size:var(--fs-micro); font-weight:500; color:var(--text-2); background:var(--surface-2); border-radius:var(--r-full); padding:var(--s-1) var(--s-3); }
.state::before{ content:""; width:6px; height:6px; border-radius:var(--r-full); background:var(--teal); flex-shrink:0; }
.state-soon::before{ background:var(--n-400); }

/* the trust line under the CTA, and the rank 1 fix card under the score */
.trust{ font-size:var(--fs-xs); color:var(--text-3); line-height:var(--lh-ui); max-width:56ch; }
.trust b{ color:var(--text-2); font-weight:600; }
.topfix{ display:flex; gap:var(--s-4); align-items:flex-start; background:var(--surface); border-radius:var(--r-lg); box-shadow:var(--e1); padding:var(--s-4) var(--s-5); margin-top:var(--s-4); }
.topfix .tf-n{ width:24px; height:24px; border-radius:var(--r-full); background:var(--terra-tint); color:var(--terra); font-family:var(--font-mono); font-size:var(--fs-micro); font-weight:600; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.topfix b{ display:block; font-size:var(--fs-body); font-weight:600; }
.topfix p{ font-size:var(--fs-xs); color:var(--text-2); margin-top:var(--s-1); line-height:var(--lh-ui); }
.topfix .btn{ margin-top:var(--s-3); }

/* icon holder: icons stop shifting the baseline of the text beside them */
.ic{ display:inline-flex; align-items:center; justify-content:center; vertical-align:middle; flex-shrink:0; line-height:0; }
.ic svg{ display:block; }

/* ---------- header v2 ----------
   The shared script upgrades the static header in place on every page. These
   rules live here so hub-account.js can drop injectStyle() entirely. */
.acct-link{ display:inline-flex; align-items:center; gap:var(--s-2); font-size:var(--fs-sm); font-weight:500; color:var(--text-2); text-decoration:none; white-space:nowrap; transition:color var(--dur-1) var(--ease-out); }
.acct-link:hover{ color:var(--teal); }
/* the name inside the header chip. hub-account.js writes it on every paint and
   it had no rule, so a long name pushed the badge and the CTA off the bar. */
.acct-name{ font-size:var(--fs-micro); font-weight:500; color:var(--ink);
  max-width:12ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.acct-link .badge{ font-size:var(--fs-micro); padding:2px var(--s-2); }
.hub-prod{ position:relative; display:inline-flex; }
.hub-prod-btn{ display:inline-flex; align-items:center; gap:var(--s-1); background:none; border:none; font-family:inherit; font-size:var(--fs-sm); font-weight:500; color:var(--text-2); padding:var(--s-2) 0; transition:color var(--dur-1) var(--ease-out); }
.hub-prod-btn:hover, .hub-prod[data-open="1"] .hub-prod-btn{ color:var(--teal); }
.hub-prod-btn .ic{ transition:transform var(--dur-2) var(--ease-out); }
.hub-prod[data-open="1"] .hub-prod-btn .ic{ transform:rotate(180deg); }
.hub-menu{ top:calc(100% + var(--s-2)); left:0; min-width:280px; }
@media (max-width:960px){ .hub-prod{ display:none; } }

/* =====================================================================
   THE .av-* REPORT NAMESPACE.
   Authored here so wave 2 can delete the ~150 line CSS constant and
   injectCss() from assets/audit-view.js. The two hardcoded #a16207 in that
   string become var(--warn) here.
   ===================================================================== */
.av{ display:block; }
.av .av-card{ background:var(--surface); border-radius:var(--r-lg); box-shadow:var(--e1); padding:var(--s-5); margin-top:var(--s-4); }
.av .av-card:first-child{ margin-top:0; }
/* nested in the workspace the report sits ON a surface, so it takes the
   hairline instead of a second elevation */
.av.av-compact .av-card{ padding:var(--s-4); margin-top:var(--s-3); box-shadow:none; border:1px solid var(--hairline); }

/* the soft head bar, light on purpose. The one teal surface is the rail. */
.av .av-bar{ display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap; background:var(--teal-soft); border-radius:var(--r-lg); padding:var(--s-3) var(--s-4); margin-bottom:var(--s-4); }
.av .av-bar .av-dom{ font-family:var(--font-mono); font-size:var(--fs-body); font-weight:600; word-break:break-all; }
.av .av-bar .av-meta{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-1); }
.av .av-bar .av-sp{ margin-left:auto; display:flex; gap:var(--s-2); flex-wrap:wrap; }
/* the compacting sticky report head, carrying both numbers for the long scroll */
.av .av-head{ position:sticky; top:60px; z-index:var(--z-sticky); background:var(--surface); box-shadow:var(--e2); border-radius:var(--r-lg); padding:var(--s-3) var(--s-4); display:none; align-items:center; gap:var(--s-4); }
.av .av-head.on{ display:flex; }
.av .av-head .n{ font-family:var(--font-mono); font-weight:700; font-variant-numeric:tabular-nums; font-size:var(--fs-num-sm); }

/* banners */
.av .av-banner{ display:flex; gap:var(--s-3); align-items:flex-start; border-radius:var(--r-lg); padding:var(--s-3) var(--s-4); margin-bottom:var(--s-4); background:var(--surface); box-shadow:var(--e1); }
.av .av-banner .av-bic{ width:26px; height:26px; border-radius:var(--r-md); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.av .av-banner b{ display:block; font-size:var(--fs-body); font-weight:600; }
.av .av-banner p{ font-size:var(--fs-xs); color:var(--text-2); margin-top:var(--s-1); line-height:var(--lh-ui); }
.av .av-bad-b{ background:var(--bad-bg); box-shadow:none; border:1px solid var(--bad-line); }
.av .av-bad-b .av-bic{ background:var(--surface); color:var(--bad); }
.av .av-note-b{ background:var(--surface-2); box-shadow:none; border:1px solid var(--hairline); }
.av .av-note-b .av-bic{ background:var(--teal-soft); color:var(--teal); }

/* card heads */
.av .av-h{ display:flex; align-items:center; gap:var(--s-3); padding-bottom:var(--s-3); border-bottom:1px solid var(--hairline); flex-wrap:wrap; }
.av .av-h .av-ic{ width:26px; height:26px; border-radius:var(--r-md); background:var(--teal-soft); color:var(--teal); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.av .av-h b{ font-size:var(--fs-lead); font-weight:600; letter-spacing:var(--ls-heading); }
.av .av-h .av-n{ margin-left:auto; font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3); white-space:nowrap; }
.av.av-compact .av-h b{ font-size:var(--fs-sm); }

/* the score head, built on THE PAIR */
.av .av-score{ display:flex; gap:var(--s-6); align-items:center; flex-wrap:wrap; }
.av .av-side{ flex:1; min-width:240px; }
.av .av-verdict{ font-size:var(--fs-h2); font-weight:600; letter-spacing:var(--ls-heading); line-height:var(--lh-heading); }
.av .av-side p{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-1); }
.av .av-bars{ margin-top:var(--s-3); }
.av .av-brow{ display:flex; align-items:center; gap:var(--s-3); padding:var(--s-1) 0; }
.av .av-brow .k{ font-size:var(--fs-xs); color:var(--text-2); width:172px; flex-shrink:0; }
.av .av-brow .k i{ font-style:normal; color:var(--text-3); font-family:var(--font-mono); font-size:var(--fs-micro); }
.av .av-brow .bar{ flex:1; height:6px; border-radius:var(--r-full); background:var(--surface-2); border:1px solid var(--hairline); overflow:hidden; }
.av .av-brow .bar i{ display:block; height:100%; width:0; transition:width var(--dur-data) var(--ease-data); }
.av .av-brow .n{ font-family:var(--font-mono); font-size:var(--fs-xs); width:34px; text-align:right; font-variant-numeric:tabular-nums; }

/* checks */
.av .av-chk{ display:flex; gap:var(--s-3); padding:var(--s-3) 0; border-bottom:1px solid var(--hairline); align-items:flex-start; }
.av .av-chk:last-child{ border-bottom:none; }
.av .av-chk .body{ flex:1; min-width:0; }
.av .av-chk .lab{ display:flex; justify-content:space-between; gap:var(--s-3); align-items:baseline; flex-wrap:wrap; }
.av .av-chk .lab b{ font-size:var(--fs-sm); font-weight:600; }
.av .av-chk .lab .v{ font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-2); word-break:break-word; }
.av .av-chk .so{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-1); line-height:var(--lh-ui); }
/* the report's verdict chips are the shared vocabulary, one set of values */
.av .av-st{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; padding:var(--s-1) var(--s-2); border-radius:var(--r-xs); white-space:nowrap; flex-shrink:0; margin-top:2px; width:54px; text-align:center; }
.av .av-st-pass{ color:var(--good); background:var(--good-bg); }
.av .av-st-warn{ color:var(--warn); background:var(--warn-bg); }
.av .av-st-fail, .av .av-st-fix{ color:var(--bad); background:var(--bad-bg); }
.av .av-st-skip{ color:var(--text-3); background:var(--surface-2); }
.av .av-subs{ margin-top:var(--s-2); }
.av .av-sub{ display:flex; justify-content:space-between; gap:var(--s-3); align-items:baseline; padding:var(--s-2) 0; font-size:var(--fs-xs); border-bottom:1px solid var(--hairline); }
.av .av-sub:last-child{ border-bottom:none; }
.av .av-sub .k{ color:var(--text-2); }
.av .av-sub .v{ font-family:var(--font-mono); font-size:var(--fs-micro); text-align:right; word-break:break-word; }
.av .av-sub .v.good{ color:var(--good); }
.av .av-sub .v.bad{ color:var(--bad); }
.av .av-sub .v.warn{ color:var(--warn); }
.av .av-sub .v.mute{ color:var(--text-3); }
.av .av-note{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-3); line-height:var(--lh-ui); }

/* fixes, including the ghosted locked tail */
.av .av-fix{ display:flex; gap:var(--s-3); padding:var(--s-3) 0; border-bottom:1px solid var(--hairline); align-items:flex-start; }
.av .av-fix:last-child{ border-bottom:none; }
.av .av-fix .n{ width:24px; height:24px; border-radius:var(--r-full); background:var(--terra-tint); color:var(--terra); font-family:var(--font-mono); font-size:var(--fs-micro); font-weight:600; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.av .av-fix b{ font-size:var(--fs-sm); font-weight:600; }
.av .av-fix .do{ font-size:var(--fs-sm); color:var(--text-2); margin-top:var(--s-1); }
.av .av-fix .why{ font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-1); }
.av .av-fix .sec{ font-size:var(--fs-micro); color:var(--text-3); font-family:var(--font-mono); }
.av .av-fix-ghost{ opacity:0.45; }
.av .av-fix-ghost .n{ background:var(--surface-2); color:var(--text-3); }

/* the written read */
.av .av-read p{ font-size:var(--fs-sm); color:var(--text-2); margin-top:var(--s-3); line-height:var(--lh-body); }
.av .av-read p:first-child{ margin-top:var(--s-2); }

/* the lock, a card that names what is missing. Nothing sent is ever blurred. */
.av .av-lock{ display:flex; gap:var(--s-3); align-items:flex-start; background:var(--surface-2); border:1px solid var(--hairline); border-radius:var(--r-lg); padding:var(--s-4); margin-top:var(--s-3); }
.av .av-lock .av-lic{ width:30px; height:30px; border-radius:var(--r-md); background:var(--surface); border:1px solid var(--hairline); color:var(--teal); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.av .av-lock b{ display:block; font-size:var(--fs-body); font-weight:600; }
.av .av-lock p{ font-size:var(--fs-xs); color:var(--text-2); margin-top:var(--s-1); line-height:var(--lh-ui); }
.av .av-lock .av-cta{ margin-top:var(--s-3); display:flex; gap:var(--s-3); align-items:center; flex-wrap:wrap; }
.av .av-lock .av-lk{ font-size:var(--fs-micro); color:var(--text-3); }
.av .av-lock a.av-link{ color:var(--terra); font-weight:600; text-decoration:none; }
.av .av-lock a.av-link:hover{ text-decoration:underline; }

/* speed tiles */
.av .av-tiles{ display:grid; grid-template-columns:repeat(var(--tile-cols,4),minmax(0,1fr)); gap:var(--s-3); margin-top:var(--s-3); }
.av .av-tiles.t3{ --tile-cols:3; }
.av .av-tile{ background:var(--surface-2); border-radius:var(--r-md); padding:var(--s-3); min-width:0; }
.av .av-tile .lbl{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--text-3); }
.av .av-tile .val{ font-family:var(--font-mono); font-size:var(--fs-num); font-weight:700; margin-top:var(--s-1); font-variant-numeric:tabular-nums; }
.av .av-tile .val small{ font-size:var(--fs-micro); color:var(--text-3); font-weight:400; }
.av .av-tile .val.good{ color:var(--good); }
.av .av-tile .val.bad{ color:var(--bad); }
.av .av-tile .val.warn{ color:var(--warn); }
.av .av-tile .cap{ font-size:var(--fs-micro); color:var(--text-3); margin-top:var(--s-1); line-height:var(--lh-ui); }
.av .av-subh{ font-size:var(--fs-micro); font-weight:600; letter-spacing:var(--ls-label); text-transform:uppercase; color:var(--text-3); margin:var(--s-4) 0 2px; }
.av .av-skel{ height:11px; border-radius:var(--r-xs); background:var(--surface-2); background-image:linear-gradient(90deg,transparent 0%,rgba(255,255,255,0.85) 50%,transparent 100%); background-size:200% 100%; background-repeat:no-repeat; animation:hub-shimmer 1.4s var(--ease-out) infinite; }
.av .av-loading{ font-size:var(--fs-xs); color:var(--text-3); display:flex; align-items:center; gap:var(--s-2); margin-top:var(--s-3); }

/* the Pro card, a plain soft card. The edge stripe is deleted. */
.av .av-pro{ margin-top:var(--s-4); border-radius:var(--r-lg); overflow:hidden; box-shadow:var(--e1); background:var(--surface); }
.av .av-pro .av-pro-h{ background:var(--teal-soft); padding:var(--s-3) var(--s-4); display:flex; align-items:center; gap:var(--s-3); flex-wrap:wrap; }
.av .av-pro .av-pro-h b{ font-size:var(--fs-sm); font-weight:600; }
.av .av-pro .av-pro-h span{ font-size:var(--fs-xs); color:var(--text-2); }
.av .av-pro .av-pro-b{ padding:var(--s-4); display:flex; gap:var(--s-4); flex-wrap:wrap; align-items:flex-start; }
.av .av-pro ul{ list-style:none; display:grid; grid-template-columns:1fr 1fr; gap:var(--s-1) var(--s-4); flex:1; min-width:240px; }
.av .av-pro li{ font-size:var(--fs-xs); color:var(--text-2); padding-left:var(--s-3); position:relative; }
.av .av-pro li::before{ content:""; position:absolute; left:0; top:8px; width:5px; height:5px; border-radius:var(--r-full); background:var(--teal); }
.av .av-pro .av-pro-cta{ display:flex; flex-direction:column; align-items:flex-start; gap:var(--s-2); }
.av .av-pro .av-pro-cta span{ font-size:var(--fs-micro); color:var(--text-3); max-width:220px; }

/* the run screen. Only the step actually in flight spins. */
.av .av-run{ max-width:640px; }
.av .av-steps{ list-style:none; margin-top:var(--s-3); }
.av .av-step{ display:flex; align-items:flex-start; gap:var(--s-3); padding:var(--s-3) 0; border-bottom:1px solid var(--hairline); }
.av .av-step:last-child{ border-bottom:none; }
.av .av-step .sic{ width:19px; height:19px; flex-shrink:0; border-radius:var(--r-full); border:2px solid var(--n-200); margin-top:2px; display:flex; align-items:center; justify-content:center; color:var(--on-dark); }
.av .av-step .sic svg{ display:none; }
.av .av-step.run .sic{ border-top-color:var(--teal); animation:hub-spin 0.8s linear infinite; }
.av .av-step.wait .sic{ opacity:0.4; animation:none; }        /* honest: not started */
.av .av-step.done .sic{ background:var(--good); border-color:var(--good); animation:none; }
.av .av-step.done .sic svg{ display:block; }
.av .av-step.skip .sic{ border-style:dashed; animation:none; }
.av .av-step b{ font-size:var(--fs-body); font-weight:600; }
.av .av-step em{ display:block; font-style:normal; font-size:var(--fs-xs); color:var(--text-3); margin-top:var(--s-1); }
.av .av-step .res{ margin-left:auto; font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3); white-space:nowrap; padding-left:var(--s-3); }
.av .av-elapsed{ font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-3); font-variant-numeric:tabular-nums; }
.av .av-prog{ height:6px; border-radius:var(--r-full); background:var(--surface-2); overflow:hidden; margin-top:var(--s-3); }
.av .av-prog i{ display:block; height:100%; width:0; background:var(--teal); transition:width var(--dur-3) var(--ease-out); }
.av .av-spin{ width:12px; height:12px; border:2px solid var(--n-200); border-top-color:var(--teal); border-radius:var(--r-full); animation:hub-spin 0.8s linear infinite; flex-shrink:0; }

/* failure */
.av .av-fail{ max-width:620px; }
.av .av-fic{ width:30px; height:30px; border-radius:var(--r-md); background:var(--bad-bg); color:var(--bad); display:inline-flex; align-items:center; justify-content:center; }
.av .av-fail h2{ font-size:var(--fs-h2); font-weight:600; letter-spacing:var(--ls-heading); margin-top:var(--s-3); }
.av .av-fail p{ font-size:var(--fs-body); color:var(--text-2); margin-top:var(--s-2); line-height:var(--lh-ui); }
.av .av-fail details{ margin-top:var(--s-3); }
.av .av-fail summary{ font-size:var(--fs-xs); color:var(--text-3); cursor:pointer; }
.av .av-fail .av-meta2{ font-family:var(--font-mono); font-size:var(--fs-micro); color:var(--text-3); margin-top:var(--s-3); word-break:break-all; }
.av .av-acts{ display:flex; gap:var(--s-3); flex-wrap:wrap; margin-top:var(--s-4); align-items:center; }

@media (max-width:760px){
  .av .av-tiles, .av .av-tiles.t3{ --tile-cols:2; }
  .av .av-pro ul{ grid-template-columns:1fr; }
}
@media (max-width:600px){
  .av .av-card{ padding:var(--s-4); }
  .av .av-score{ gap:var(--s-4); }
  .av .av-brow .k{ width:126px; }
  .av .av-pro-cta, .av .av-pro-cta .btn{ width:100%; }
  .scorepair{ gap:var(--s-5); }
  .ring-report{ --ring-size:104px; --ring-w:6; }
}
@media (max-width:430px){
  .av .av-tiles, .av .av-tiles.t3{ --tile-cols:1; }
  .av .av-step .res{ display:none; }
}

/* ---------- Layout utilities ---------- */
.grid-3{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--s-4); }
.grid-4{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--s-4); }
.grid-6{ display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:var(--s-3); }
.section{ padding:var(--space-section) 0; }
.section-tight{ padding:var(--space-section-tight) 0; }
/* anchor links clear the 60px sticky header */
section[id]{ scroll-margin-top:76px; }
.mt-1{ margin-top:var(--s-2); }
.mt-2{ margin-top:var(--s-4); }
.mt-3{ margin-top:var(--s-5); }
.mt-4{ margin-top:var(--s-6); }
.mt-5{ margin-top:var(--s-8); }
.mb-2{ margin-bottom:var(--s-4); }
.mb-3{ margin-bottom:var(--s-5); }
.center{ text-align:center; }
.row{ display:flex; align-items:center; gap:var(--s-3); }
.spread{ display:flex; align-items:center; justify-content:space-between; gap:var(--s-4); flex-wrap:wrap; }

@media (max-width:960px){
  .hub-links{ display:none; }
  .grid-4, .pick-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .grid-6{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .grid-3{ grid-template-columns:1fr; }
  .tool-grid2{ grid-template-columns:1fr; }
}
@media (max-width:600px){
  .pick-grid, .grid-4{ grid-template-columns:1fr; }
  .grid-6{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .band-dark{ padding:var(--s-5) var(--s-4); }
}
@media (max-width:430px){
  /* keep the 60px header bar intact on small phones (flagged by page QA) */
  .hub-nav{ gap:var(--s-3); }
  .hub-brand b{ font-size:var(--fs-micro); letter-spacing:var(--ls-label); }
  .hub-right .btn{ padding:var(--btn-py-sm) var(--btn-px-sm); font-size:var(--fs-xs); white-space:nowrap; }
}

/* ---------- App density, the page-owned classes ----------
   Every hub.css component already reads the token overrides at the top of
   .ui-dense. These four lines only reach classes that pages own. */
.ui-dense .tp{ padding:var(--space-card); }
.ui-dense .card-h b, .ui-dense .card-h > b{ font-size:var(--fs-sm); }
.ui-dense .eyebrow{ font-size:var(--fs-micro); }
.ui-dense .verdict, .ui-dense .note{ font-size:var(--fs-xs); }

/* ---------- Reduced motion, a SCOPED policy, not a blanket kill ----------
   The old `* { transition:none; animation:none }` froze the only signal that a
   20 second run is alive, and would strand any opacity:0 entrance invisible. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ transition-duration:1ms !important; transition-delay:0ms !important; }
  :root{ --dur-1:1ms; --dur-2:100ms; --dur-3:100ms; --dur-data:1ms;
         --dur-press:1ms; --lift:0px; --lift-toast:0px; }
  .spin, .av .av-spin, .av .av-step.run .sic{ animation-duration:0.8s !important; }
  .skel, .av .av-skel{ animation:none !important; opacity:0.7; }
}

/* ---------- Header v2 (upgraded in place by hub-account.js) ----------
   These lived inside a JavaScript string until the design pass. They belong
   here so the header is auditable CSS like everything else. */
.hh2-links { display: flex; align-items: center; gap: 4px; flex: 1; margin-left: 18px; }
.hh2-links > a, .hh2-prod > button {
  font-size: var(--fs-sm, 13px); font-weight: 600; color: var(--text-2);
  text-decoration: none; padding: 7px 11px; border-radius: var(--r-sm, 8px);
  background: none; border: none; cursor: pointer; font-family: var(--font-sans);
  line-height: 1.2; white-space: nowrap;
}
.hh2-links > a:hover, .hh2-prod > button:hover { background: var(--surface-2, #f9fafb); color: var(--text-1); }
.hh2-links > a.on { color: var(--teal, #2c687a); }
.hh2-prod { position: relative; }
.hh2-prod > button::after {
  content: ""; display: inline-block; margin-left: 6px;
  border: 4px solid transparent; border-top-color: currentColor; transform: translateY(2px);
}
.hh2-menu {
  position: absolute; top: calc(100% + 10px); left: 0; z-index: 60;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-card, 14px); box-shadow: var(--e2, 0 12px 28px -8px rgba(17,24,39,.14));
  padding: 10px; display: none; grid-template-columns: repeat(2, minmax(230px, 1fr)); gap: 2px;
}
.hh2-prod.open .hh2-menu { display: grid; }
.hh2-item { display: flex; gap: 11px; align-items: flex-start; padding: 10px 11px; border-radius: var(--r-sm, 8px); text-decoration: none; }
.hh2-item:hover { background: var(--surface-2, #f9fafb); }
.hh2-item .ic {
  width: 34px; height: 34px; border-radius: var(--r-sm, 8px); border: 1px solid var(--hairline);
  display: flex; align-items: center; justify-content: center; color: var(--teal, #2c687a);
  flex-shrink: 0; background: var(--surface);
}
.hh2-item b { display: block; font-size: var(--fs-sm, 13px); color: var(--text-1); line-height: 1.3; }
.hh2-item span { display: block; font-size: var(--fs-xs, 12px); color: var(--text-3); line-height: 1.35; margin-top: 1px; }
.hh2-right { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.hh2-ws {
  display: inline-flex; align-items: center; background: var(--teal, #2c687a); color: var(--on-dark, #fff);
  font-size: var(--fs-sm, 13px); font-weight: 700; padding: 8px 16px;
  border-radius: var(--r-sm, 8px); text-decoration: none; white-space: nowrap;
}
.hh2-ws:hover { background: var(--teal-deep, #245666); }
@media (max-width: 760px) {
  .hh2-menu { grid-template-columns: 1fr; left: auto; right: 0; }
  .hh2-links { gap: 0; margin-left: 6px; }
  .hh2-links > a[data-sec] { display: none; }
}
