/* ============================================================================
   followupr — SAFELIFT THEME
   The single source of truth for tokens, type and component recipes.
   Implements C:/Users/PatHel/crm-dialer/THEME-SPEC.md (2026-08-29). If this
   file and that document disagree, the document is right and this is a bug.
   ----------------------------------------------------------------------------

   WHY THIS FILE EXISTS AT ALL
   Thirteen pages each carry a complete inline copy of a different design system
   (the Chakra "Purity UI" dashboard template). This stylesheet wins for exactly
   one reason: its <link> is the line immediately after </style> on all thirteen
   pages, so at equal specificity it lands last and takes the cascade.
   ⛔ KEEP IT LAST. There is no error and no visible symptom if that breaks —
   the app silently reverts to a teal Chakra dashboard. That ordering is why
   almost nothing here needs extra specificity, and why it must not grow any.

   WHERE THE DESIGN COMES FROM — measured, not remembered
   Evidence: ~/safelift-brand/design-system.md, website-audit-2026-08-20.md
   (73 site pages + 29 published PDFs) and pdf-color-evidence.txt (per-PDF
   vector fill counts). The three facts that decide most of this file:

     · The 2026 brochure's own ink counts are charcoal #292829 (236 fills),
       body grey #414042 (157) and yellow #ffc415≈#ffc310 (71). That is the
       whole palette. Three inks, one accent.
     · The A5 manuals add exactly three more: light block #f2f0eb (36-47 fills),
       safety red #d2232a (32-34) and diagram blue #005596 (14-19).
     · safelift.se publishes its button as: text #333 on #ffc310, radius 3px.
       That single spec sets the radius for the entire system.

   PRINT NEUTRALS, NOT WEB NEUTRALS — the one place we depart from the site
   design-system.md says "the deliverable decides", and a dashboard is a web
   deliverable, which is why this file used to ship #333333/#666666. It does
   not transfer. safelift.se sets #666666 at 17px on a WHITE page (5.74:1).
   This app sets 13-15px on its own #f0f0eb ground, where the same grey is only
   5.02:1. The brochure's two inks give a clean three-step ramp on that ground —
   12.85 / 9.02 / 5.02 — instead of a two-step ramp pretending to be four.
   #414042 nearly doubles body-text contrast over #666666 for ten people
   reading this eight hours a day, and it is not a compromise with the brand:
   it IS the brand, taken from the brochures the app is meant to look like.
   ⚠ ALWAYS STATE THE GROUND IN A CONTRAST COMMENT. The old "10.9:1"/"5.7:1"
   comments here were measured against the site's white page and overstated
   real headroom by 14%.

   THE TWO FONT FILES, AND THE RULE THAT FOLLOWS FROM THEM
   static/fonts/ holds exactly two faces: Hv (Heavy — the heading voice) and
   Roman. No Bold, no Medium, no Thin, no italic, no woff2. 377 declarations
   across the pages ask for weight 500+; every one of them was a browser-
   synthesised fake bold — Roman with its outlines dilated, unmistakable at the
   27-38px where prospect names and hero numbers sit. Fixed below by declaring
   each face over the full 100-900 range and switching font-synthesis off.

   ⛔ STANDING RULE FOR ALL FUTURE EDITS: never write font-weight in a page
   style block. If something should be heavier, give it font-family:
   var(--font-display). Never write font-style:italic — no italic file exists
   and a synthetic slant reads as a rendering fault.

   ⛔ Yellow is a FILL, never text on a light ground (#ffc310 on #f0f0eb is
   1.41:1). Its text voice on light grounds is --accent-ink #7a5c00. The ONE
   legitimate yellow-as-text in the product is the active nav item on the dark
   band, 9.90:1 — the site's own signature. Do not sweep that away.

   ⛔ #fecc00 and #006aa7 are the SWEDISH FLAG's colours, not brand colours.
   Same for #c8102e/#012169 (Union Jack) and the rest. This app draws 28
   country flags as inline SVG, and flag hexes inside a flag graphic are
   CORRECT. Flag hexes used as layout, text or accent colour are a bug.
   There is no teal in this system. Both mistakes were made before.

   ⛔ Never introduce a colour that is not in the token table below.
   ========================================================================== */

@font-face{
  font-family:'HelveticaNeueLTW1G-Hv';
  src:url('fonts/HelveticaNeueLTW1G-Hv.woff') format('woff');
  /* The file is one weight. Declaring it across 100-900 makes every weight
     request match the real outlines instead of triggering synthesis.
     Relative URL: resolved against /static/theme.css, so identical today but
     it survives being mounted under a reverse-proxy prefix — where the old
     absolute /static/... 404'd silently and the whole app fell back to Arial. */
  font-weight:100 900; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'HelveticaNeueLTW1G-Roman';
  src:url('fonts/HelveticaNeueLTW1G-Roman.woff') format('woff');
  font-weight:100 900; font-style:normal; font-display:swap;
}

/* ============================================================================
   THE TOKEN TABLE — the contract.
   No page may declare a value for anything in here.
   ========================================================================== */
:root{
  color-scheme: light;

  /* ---------- 1. SURFACES — cool, not warm ----------
     ⚠ 2026-08-29, SECOND PASS. Patrick saw the brochure version and said "the
     design is super ugly, I want a futuristic version", then chose the LIGHT
     direction over the dark one. So the grounds moved from the brochure's warm
     paper (#f0f0eb, a beige) to a cool near-white. Same brightness he asked for
     originally, none of the printed-page flatness.
     The brochure inks stay in the file's history above; the accent and the
     Safelift yellow are untouched. This is an internal tool, not a customer
     document — the standing "everything branded" rule governs documents. */
  --bg:        #f4f6f9;   /* page ground — cool near-white */
  --bg-deep:   #e9edf3;   /* recessed one step below --bg */
  --bg-lift:   #ffffff;   /* raised ground */
  --card:      #ffffff;   /* panels FLOAT on the ground now — see §2 */
  --card-2:    #f8fafc;   /* secondary card / inner panel */
  --well:      #f4f6f9;   /* inset well — callouts and spec tables sit on this */
  --sunken:    #e9edf3;   /* track/groove behind meters and toggles */
  --scrim:     rgba(15,23,41,.55);   /* cool, matches the new ink */

  /* ---------- 2. ELEVATION — depth is the point now ----------
     The printed corpus separates blocks with TONE and RULES and no shadow at
     all, and this file used to enforce that by setting every elevation token to
     none. On paper that is right. On a screen someone stares at for eight hours
     it read as flat and dead, which is what Patrick meant by "super ugly".
     A light cockpit gets its structure from LIFT: white panels above a cool
     ground, with a short two-layer cast. Short and tight, never a soft blur —
     a big fuzzy shadow is the 2015 dashboard look we are moving away from.
     ⛔ Every shadow in this file is rgba(15,23,41,…) — the ink, at low alpha.
     Never a grey or black shadow: those go muddy over a cool ground.
     --sh/--sh-soft/--sh2/--shadow stay `none` ON PURPOSE. They are the four
     names the old template's pages reach for, and letting them resolve would
     scatter uncontrolled casts across 100+ elements. Depth is applied
     deliberately, by recipe, not by a page asking for it. */
  --e1: 0 1px 2px rgba(15,23,41,.04), 0 2px 6px -1px rgba(15,23,41,.06);
                     /* THE CARD CAST — 96 references. Two layers: a tight one
                        for the edge, a wider soft one for the lift. This is the
                        change that makes a panel float instead of sit. */
  --e2: 0 2px 4px rgba(15,23,41,.04), 0 10px 24px -8px rgba(15,23,41,.12);
                     /* menus, popovers, anything above a card */
  --sh:      none;   /* page alias — 6 refs */
  --sh-soft: none;   /* page alias — 3 refs. Declared HERE for the first time;
                        while it was page-owned it was how shadows leaked back. */
  --sh2:     none;   /* page alias, currently unreferenced — completes the set */
  --shadow:  none;   /* page alias that used to resolve to --e3, putting a 48px
                        modal shadow on every classic.html card */
  --e3: 0 24px 64px -24px rgba(15,23,41,.30), 0 2px 8px rgba(15,23,41,.06);
                    /* TRUE MODAL OVERLAYS ONLY: .bug-card, .edit-card,
                       .sheet-inner. Nothing else. */
  --e-inset:        inset 0 1px 2px rgba(15,23,41,.06);  /* inset well, not a cast */
  --e-press:        inset 0 2px 4px rgba(15,23,41,.12);
  --e-accent:       0 2px 10px -2px rgba(255,195,16,.55);  /* the primary action
                       carries a little of its own light. The ONE coloured cast
                       in the system — reserved for the yellow button. */
  --e-accent-press: inset 0 2px 4px rgba(15,23,41,.22);
  --e-danger:       none;   /* danger states argue with colour, not with glow */

  /* ---------- 3. TEXT — three cool inks ----------
     Ratios measured against THIS app's grounds. The brochure's warm charcoal
     and body grey were correct on paper and looked yellowed next to a cool
     white panel, so all three steps moved onto the same cool axis as the
     surfaces. The RAMP is unchanged: three steps, hierarchy from size and the
     Heavy face, not from a fourth grey nobody can tell apart from the third. */
  --ink:   #0f1729;   /* headings, prospect names, primary values.
                         16.51 on --bg · 17.87 on --card · 15.21 on --bg-deep */
  --muted: #3d4a5c;   /* body, table values, card copy.
                         8.32 on --bg · 9.00 on --card · 7.66 on --bg-deep */
  --faint: #5b6779;   /* captions, meta, timestamps.
                         5.30 on --bg · 5.74 on --card · 4.88 on --bg-deep
                         ⚠ the obvious slate #64748b lands at 4.40 on --bg and
                         4.05 on --bg-deep — both under 4.5. One step darker. */
  --ghost: #5b6779;   /* DOCUMENTED ALIAS of --faint. 37 references; keeping the
                         name avoids a rename across thirteen files. */
  --on-accent: #333333;  /* text ON the yellow fill — the site's published button
                         spec, 7.86:1. NEVER white (#fff on #ffc310 is 1.61:1,
                         below the 1.9:1 point where a lettershape stops
                         resolving). Deliberately NOT the same hex as --ink, so
                         the two roles can no longer be confused. */
  --on-solid:  #ffffff;  /* text on any dark semantic fill.
                         5.23 on #d2232a · 6.92 on #b01c22 · 5.35 on #1d7a45 ·
                         8.04 on #155c34 · 7.66 on #005596 */

  /* ---------- 4. LINES ---------- */
  --line:   #e3e8ef;  /* decorative hairline between two light surfaces — card
                         borders, row separators. Correctly EXEMPT from WCAG
                         1.4.11 because it is decorative. With --e1 doing the
                         separating now, this is lighter than it used to be:
                         a panel that both casts a shadow AND carries a strong
                         border looks drawn twice. */
  --line-2: #d4dbe5;  /* stronger hairline; menu and popover edges */
  --edge:   #b7c0cd;  /* scrollbar thumb hover, heavier dividers */
  --control-edge: #7c8798;  /* THE BOUNDARY OF AN INTERACTIVE CONTROL — input,
                         select, textarea, any bordered button. WCAG 1.4.11
                         wants 3:1 and none of the three above clears it.
                         3.64 on #ffffff · 3.36 on --bg */

  /* ---------- 5. THE ACCENT — Safelift yellow ---------- */
  --accent:       #ffc310;  /* THE fill: buttons, rails, strips, active states.
                               The one human-typed yellow in the corpus; print
                               exports vary #ffc205/#ffc415/#fdc500 as ICC noise
                               around this same swatch. */
  --accent-ink:   #7a5c00;  /* yellow's TEXT voice on light grounds — eyebrows,
                               links, quiet accents. 5.47 on --bg. */
  --accent-lite:  #ffd45c;  /* light tint, large fills only */
  --accent-hover: #f0b600;
  --accent-press: #e0a900;
  --accent-soft:  #fff6dc;  /* pale yellow chip/callout ground */
  --accent-line:  #f4dfa0;  /* pale yellow border. BORDER ONLY — never text. */
  --accent-ring:  rgba(255,195,16,.55);  /* the halo around the focus ring */
  --grad-accent:       linear-gradient(180deg,#ffc310,#ffc310);  /* flat yellow as
                               a gradient, because ~30 page rules pass it to
                               background: and expect a gradient */
  --grad-accent-hover: linear-gradient(180deg,#f0b600,#f0b600);
  --grad-viz:          linear-gradient(180deg,#ffc310,#e0a900);
  --sunny:     #ffd45c;   /* live legacy alias — 1 use, index.html */
  --tangerine: #8a5a00;   /* live legacy alias — 2 uses, the ringing/busy dot */

  /* ---------- 6. SEMANTIC — a SEPARATE AXIS from the brand accent ----------
     The brand palette is charcoal, grey and one yellow. State colour must not
     collapse into it. Yellow is simultaneously the brand accent AND the
     warm/warning register, so --warn-solid must not be the accent or "warning"
     becomes invisible. */
  --ok:        #14663a;   /* success TEXT. Darkened one step from the fill —
                             #1d7a45 failed at 4.35:1 on --bg-deep/--sunken.
                             6.14 on --bg · 5.71 on --bg-deep */
  --ok-solid:  #1d7a45;   /* success FILL. Green is not in the Safelift corpus at
                             all (the only published green is the manuals'
                             tick-mark #008b44, 6 fills in one document). This is
                             an app state colour, recorded so nobody invents a
                             second one. */
  --ok-soft:   #e8f4ec;
  --ok-line:   #bfe0cc;   /* BORDER ONLY — never text (1.05-1.32:1) */
  --warn:      #8a5a00;   /* warning TEXT — dark yellow */
  --warn-solid:#8a5a00;   /* warning FILL. Was #ffc310 — byte-identical to
                             --accent. That collision painted "we phoned them"
                             and "we mailed them" the same colour on the
                             follow-up history strip, and made an informational
                             callout indistinguishable from a warning one. */
  --warn-soft: #fff6dc;   /* shares a value with --accent-soft ON PURPOSE: the
                             corpus does treat note-blocks as yellow */
  --warn-line: #f4dfa0;   /* BORDER ONLY */
  --danger:      #b01c22; /* danger TEXT — the fill lands on 4.49:1 as text on
                             the pale red chip, so the text voice is one darker */
  --danger-solid:#d2232a; /* danger FILL and BORDER — the manuals' published
                             safety red. RESERVED FOR DANGER. Never decorative. */
  --danger-soft: #fbeaea;
  --danger-line: #f0c4c5; /* BORDER ONLY */
  --info:       #005596;  /* the manuals' diagram blue */
  --info-solid: #005596;  /* technical/diagram and data-viz only — NEVER a
                             layout accent (design-system.md is explicit) */
  --info-soft:  #e6eef5;
  --grad-danger: linear-gradient(180deg,#d2232a,#b01c22);
  --grad-ok:     linear-gradient(180deg,#1d7a45,#155c34);

  /* ---------- 7. DATA VIZ ----------
     These deliberately alias the semantic set. The corpus contains one accent
     plus two technical colours; a neutral five-series ramp does not exist in
     it, and in this app every chart series IS a status.
     ⛔ A SIXTH SERIES MUST BE A TINT OF #292829, NEVER A NEW HUE. */
  --viz-1:#ffc310; --viz-2:#7c8798; --viz-3:#1d7a45;
  --viz-4:#005596; --viz-5:#d2232a;
  --viz-grid:#e3e8ef;
  --viz-fill:rgba(255,195,16,.22);

  /* ---------- 8. THE DARK BAND — the site's masthead, turned on its side ----
     safelift.se's #222 header band: white wordmark left, active item yellow.
     Stood on end, it is this app's sidebar. Ratios against #222222. */
  --band:       #0f1729;   /* the ink itself, used as a surface — so the one
                              dark object on screen belongs to the same cool
                              axis as the type instead of being a neutral grey
                              slab bolted on the side */
  --band-hover: #1a2438;
  --band-rule:  #243044;
  --band-ink:   #ffffff;   /* 17.87 on the band */
  --band-muted: #b6c0d0;   /* idle nav label — 9.74 */
  --band-icon:  #8d99ad;   /* idle nav icon — 6.21 */
  --band-faint: #7a8699;   /* eyebrow / secondary — 4.85 */
  --band-deep:  #080d18;   /* deepest press state */
  /* the active nav item is Safelift yellow on the band: 11.12:1 — brighter
     here than it could ever be on a light ground, which is why it is the one
     legitimate yellow-as-text in the product */
  --rail:        216px;    /* ⚠ MUST move together with body.pu-shell padding-left */
  --rail-narrow: 58px;     /* ⚠ same pairing */

  /* ---------- 9. GEOMETRY ----------
     safelift.se publishes its button at 3px and the printed system is
     square-ish, which is where this file sat until Patrick asked for the
     futuristic version. 3px everywhere read as hard and dated on screen. The
     scale below is a real progression again — small things slightly soft, big
     panels properly rounded — which is what makes a surface read as a floating
     object rather than a box drawn on the page.
     ⛔ NOT a pill. Nothing here goes past 14px; capsules stay banned. */
  --radius:8px; --radius-sm:6px; --r:8px;
  --r-1:6px;  /* chips, badges, small tags */
  --r-2:8px;  /* buttons, inputs, selects */
  --r-3:10px; /* inner panels, wells, callouts */
  --r-4:12px; /* cards */
  --r-5:14px; /* modals and the largest surfaces */
  /* ↑ the tokens the PAGES actually read — 83 var(--r-*) refs. The original
     page values were 6/8, 10/12, 12/14/15, 15/16/20, 15/20/28px, so this
     restores the progression the pages were written against. */
  --r-pill:999px;
  /* --r-pill STAYS A PILL. Seven of its twelve consumers are genuinely round:
     both scrollbar thumbs, .callout .cdot, calendar .bar, setup .track and
     setup .meter/.meter i. The five chip consumers are squared BY SELECTOR in
     the badge recipe below, not by breaking the token. Every border-radius:50%
     in the app (20 of them) is a real circle and is left alone. */

  /* ---------- 10. SPACING (4pt grid) ---------- */
  --s-0:2px;  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px; --s-5:20px;
  --s-6:24px; --s-7:32px; --s-8:40px; --s-9:48px; --s-10:64px;

  /* ---------- 11. TYPE SCALE ----------
     Declared in px, not rem: today's rem values against the 16px root resolve
     to exactly these numbers, so this is a zero-change transcription that also
     decouples the scale from any future root-size edit. */
  --t-micro:11px;   /* eyebrow / smallest caps label */
  --t-xs:   12px;   /* micro-meta */
  --t-sm:   13px;
  --t-md:   14px;   /* dense body, table cell */
  --t-lg:   15px;
  --t-xl:   17px;   /* body — the site's own body size */
  --t-2xl:  21px;   /* h3 */
  --t-3xl:  26px;   /* h2 */
  --t-4xl:  clamp(28px, 1.2rem + 1.7vw, 38px);  /* h1 */

  /* ---------- 12. LEADING AND TRACKING ----------
     Negative tracking appears NOWHERE in the Safelift corpus. The brochures and
     manuals track text at 0 and eyebrows at +.06em — two values, against the
     twenty currently in use across the pages. */
  --lh-tight:1.12;
  --lh-snug: 1.35;
  --lh-body: 1.65;
  --ls-caps: .09em;   /* micro caps labels. Wider than the brochure's .06em:
                         on screen, letter-spaced small caps is what makes a
                         label read as instrumentation rather than as a heading.
                         The single cheapest "technical" signal there is. */
  --ls-tight:0;
  --ls-display:-.015em;  /* ⚠ DELIBERATE DEPARTURE from the printed corpus,
                         which tracks display type at 0. At 26-38px a hair of
                         negative tracking is what separates a modern interface
                         headline from a word-processor one. Display sizes only
                         — never body, never caps. */

  /* ---------- 13. FONTS AND MOTION ---------- */
  --font:         'HelveticaNeueLTW1G-Roman','Helvetica Neue',Helvetica,Arial,sans-serif;
  --font-display: 'HelveticaNeueLTW1G-Hv','Helvetica Neue',Helvetica,Arial,sans-serif;
  --mono:         ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  /* --mono is LOAD-BEARING: bugs.html declares the self-referential
     --mono:var(--mono), which is invalid-at-computed-value-time and only
     harmless because this file redeclares --mono later. Keep the name here. */
  --dur-1:120ms; --dur-2:200ms; --ease:cubic-bezier(.2,.8,.25,1);

  /* ---------- 14. THE MAP (demos.html only) ---------- */
  --sea:#eef2f7; --land:#ffffff; --land-2:#f8fafc; --border:#d4dbe5;
}

/* ============================================================================
   BASE — the prelude that used to be copy-pasted into eight pages, where it
   had already drifted three ways (three different focus rings, two ::selection
   colours, three scrollbar radii). It lives here once now.
   ========================================================================== */

/* !important #1 of 3, and the systemic one. .mailwrap, .bug-done, #bugwrap and
   #editbox are shown/hidden with the HTML [hidden] attribute from JS, and the
   UA's [hidden]{display:none} loses to ANY author display rule. Adding
   display:flex to .mailwrap renders the entire email thread permanently on the
   dialler screen, on every lead, unclosable. Only index.html's .lcwrap[hidden]
   had such a guard; this covers all of them for one line.
   THEME-SPEC.md §4.1.3 requires this declaration. */
[hidden]{display:none !important}

*{box-sizing:border-box}

html,body{
  font-family:var(--font);
  background:var(--bg);
  color:var(--muted);
  font-synthesis:none;   /* ⛔ THE ANTI-FAKE-BOLD GUARANTEE. font-synthesis is
                            inherited, so this one declaration covers the whole
                            document: no dilated outlines, and no synthetic
                            oblique either. Belt and braces with the 100-900
                            @font-face ranges above. */
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

/* ⚠ BODY ONLY — NEVER html. Eleven pages declare a rem-based --t-* scale and
   two clamp() values that resolve against the ROOT font size; font-size on html
   would silently rescale ~44 type tokens across the app.
   Leading is 1.6, not the site's 1.7, and that is a deliberate trade:
   line-height inherits, and index.html and followups.html are height:100vh
   grids with overflow:hidden. Running text gets the full 1.7 by component. */
body{ font-size:17px; line-height:1.6; }

a{color:var(--accent-ink)}
button{font-family:inherit; cursor:pointer; border:none; color:inherit}
input,textarea,select{font-family:inherit}
::selection{background:rgba(255,195,16,.45); color:var(--ink)}

::-webkit-scrollbar{width:11px; height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--line-2); border-radius:var(--r-pill);
  border:3px solid transparent; background-clip:content-box;
}
::-webkit-scrollbar-thumb:hover{background:var(--edge); background-clip:content-box}

/* !important #2 of 3. An author declaration must be !important to beat a
   running animation, so this is the correct use of the flag — and it is the
   whole point of the media query. Five pages (bugs, calendar, logos, notyours,
   team) had no reduced-motion block at all and get one here for free. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
}

/* ============================================================================
   TYPOGRAPHY
   ========================================================================== */

/* ---------- the reroute: every role that reads as heading, label, button or
   badge gets the REAL Heavy face at weight normal. With font-synthesis:none in
   place, anything left off this list flattens to plain Roman — which is why the
   list is long and specific rather than a tidy handful of tags.
   The cascade resolves per PROPERTY, not per rule: a page's
   .card h2{font-weight:700; font-size:18px} sets no font-family, so this rule
   still reaches it and the 700 is inert. Page font-weights are hygiene, not
   rendering defects. ---------- */
h1,h2,h3,h4,h5,h6,
.up-name,.who,
.logo,.brand,.word,
.lead-name,.lc-name,.mi-sub,
.empty .big,.verdict h1,
.card h2,.card-h h3,.sec h2,.ch h3,.panel h3,.dr-top h2,.tcol h3,.sheet-top h2,
.mailcard h2,.v h4,.rec h4,.wire h4,.grp>h3,
.pill-btn,.dial-btn,.save-next,.send,.btn,.oc,.mini-btn,.rc-done,.dial,.end,.rbtn,
.acts button,.filters button,.dispo button,.vbtns button,
strong,b,th,.pu-name,.warmth,.badge,
.tag,.pill,.chip,.req,.vtag,.mi-bad,.chain-badge,.up-src,.why-card .src,.queue-tag,
.wp-chip,.status-line,.provbar,.hd,.ht,.what,.wc,.lbl{
  font-family:var(--font-display);
  font-weight:normal;          /* Heavy IS the weight — never synthesise bold */
  letter-spacing:0;
}

/* .hd is a date/number run (it was set in Consolas at font-weight:700 — a mono
   fake bold sitting next to Helvetica Neue on the screen a rep stares at all
   day). The line above already takes it off mono; this lines its figures up.
   Helvetica Neue's figures are fixed-width, so mono bought nothing here. */
.hd{font-variant-numeric:tabular-nums}

/* ---------- EXCEPTION: the display numbers ----------
   The brochures set big numerals in THIN. There is no Thin file, and
   design-system.md states the substitution: Thin/Medium roles → Roman at the
   target size. Setting them in Heavy is the exact opposite of the brochure
   gesture — the numbers go blocky where the corpus goes airy. Must come AFTER
   the reroute list, which catches them via `b`. */
.chase .n,.bigweeks b,.t .n,.phone,.dialnum b,.kpi b,.stat b,.dnum b,.up-phone{
  font-family:var(--font);
  font-weight:normal;
  letter-spacing:0;
  font-variant-numeric:tabular-nums;
}

/* ---------- THE EYEBROW — the most recognisable Safelift gesture ----------
   Brochure spec: 9pt Heavy, UPPERCASE, tracking .06em. The app performed it 42
   different ways across 77 rules, with trackings of .04 through .26em — .logo
   small alone, the same element in the same header on nine pages, carried four
   different values. It is ONE thing. Must come after the reroute, which zeroes
   letter-spacing on .lbl.
   A light big number over a heavy small-caps label IS the brochure look. */
.lbl,.rc-head b,.mailwrap h3,.intel h3,.lc-sec h4,.lc-extra h4,.up-card::before,
.mi-who,.pu-va-h,.logo small,.mailcard .mh,.dialnum .dl,.stat span,
.bubble .who,table.mini th,.dnum span,.hdbox .hmeta{
  font-family:var(--font-display);
  font-weight:normal;
  font-size:var(--t-micro);        /* 11px */
  letter-spacing:var(--ls-caps);
  text-transform:uppercase;
  color:var(--faint);   /* ⚠ WAS --accent-ink, the yellow's dark voice. On the
                    warm brochure ground gold micro-caps read as an editorial
                    eyebrow, which is what they were. In the cockpit the whole
                    point is that yellow appears RARELY and means something —
                    the primary action, the active screen, the live state. A
                    label that merely names a section is not an event, so it is
                    quiet slate. 5.30:1 on --bg. */
  opacity:1;    /* the .85 wash on .logo small cost contrast for nothing */
  line-height:1.2;
}

/* The worst offender needs its SHAPE undone too. .up-card::before was a 99px
   yellow capsule floating half outside the top edge of the call card at
   top:-11px — a 2021 SaaS card-badge idiom that appears in no Safelift
   material. The brochure eyebrow is flat type sitting on the ground with
   nothing drawn around it.
   ⚠ Its colour is still overridden on the app's most-looked-at card by
   index.html's #up-block .up-card::before{color:var(--on-accent)} at (1,1,1) —
   a page edit, deliberately not fought from here with an ID or !important. */
.up-card::before{
  position:static; transform:none; top:auto; left:auto;
  display:block; background:none; box-shadow:none; border-radius:0;
  padding:0 0 6px; white-space:normal;
}

/* ---------- NO ITALICS, EVER ----------
   font-synthesis:none already kills the slant; this removes the intent.
   ⛔ THIS GUARD MUST SET font-style AND NOTHING ELSE. <i> and <em> are
   STRUCTURAL throughout this app — analytics .legend i is a 9px chart swatch,
   demos .lg i is a map legend dot, followups/calendar .bar i are progress-bar
   fills, setup .meter i is the meter fill, .pu-viewas em is the territory
   label. Touching display/width/height/background here silently destroys every
   chart legend and progress bar in the product. */
em,i,cite,address,var{font-style:normal}

/* ---------- SVG text ----------
   Eighteen SVG presentation attributes hard-code a font no stylesheet can
   otherwise reach: the country-code fallback plates ask for Manrope, which is
   neither installed nor served, so those labels render in Arial; sixteen more
   font-weight attributes sit in the analytics charts. CSS beats SVG
   presentation attributes, so one rule fixes all eighteen. At (0,0,2) it loses
   to .chart text, .clabel and .pin .cnt, all of which already name a correct
   family — so nothing that is already right changes. */
svg text{font-family:var(--font); font-weight:normal}

code,pre,.mono{font-family:var(--mono)}
button,input,select,textarea{font-family:var(--font)}

/* ---------- FOCUS ----------
   Yellow cannot carry a focus ring on a light ground: #ffc310 on #f0f0eb is
   1.41:1 against WCAG 2.4.11's 3:1 (the --accent-lite variant was worse at
   1.24:1). Seventeen rules across seven files inherited that. A dialler is a
   keyboard instrument; the ring answering "where am I about to type" has to be
   visible. So the ink does the work at 12.85:1 and the Safelift yellow stays
   on as the halo. */
:focus-visible{
  outline:2px solid var(--ink);
  outline-offset:2px;
  box-shadow:0 0 0 4px var(--accent-ring);
}
input:focus,select:focus,textarea:focus{
  outline:2px solid var(--ink); outline-offset:0;
  border-color:var(--control-edge);
  box-shadow:0 0 0 3px var(--accent-ring);
}

/* ============================================================================
   COMPONENTS
   ========================================================================== */

/* ---------- CARD ----------
   A white panel lifted off the cool ground by --e1, with a hairline so light it
   only closes the edge. The lift is the structure; the border is not doing the
   work any more, which is why --line got paler at the same time.
   ⚠ NO HOVER LIFT. The 28 translateY(-1px) hovers from the original template
   are still neutralised. Most of the surfaces below are not clickable, and a
   panel that rises when the pointer merely crosses it reads as a bug. Hover
   response is a BORDER CHANGE — see the hover rule further down.
   ⚠ .tile and .decision are deliberately NOT in this list — see below. */
.card,.up-card,.callcard,.intel,.mailcard,.mail-item,.lcwrap .lc,.panel,
.sheet-inner,.kpi,.stat,.box,.recap,.followup,.why-card,.lc-extra,.brief .bpt,
.ai-plan,.opt,.bug,.t,.day,.grp,.rec,.wire{
  background:var(--card);
  border:1px solid var(--line);
  border-radius:var(--r-4);
  box-shadow:var(--e1);
  color:var(--muted);
}
/* ⚠ THE DENSE ONES DO NOT LIFT. The recipe above covers both real panels and a
   set of small repeating cells — a calendar has 42 .day, the demo tray has a
   .t per row, the dial pad has a grid of .opt. Forty-two objects each casting
   a shadow is not depth, it is noise, and at 12px radius a dense grid starts
   to look like a bag of sweets. Same surface and the same hairline, one step
   of radius, and flat. */
.opt,.t,.day,.grp,.rec,.wire{
  border-radius:var(--r-2);
  box-shadow:none;
}
.up-card,.callcard,.intel,.mailcard{padding:22px}

/* Grounds the recipe must not flatten. All on-palette, all deliberate:
   these are the corpus's own "separate blocks with TONE" device, and
   --card-2 exists as a token precisely for them. */
.recap,.grp,.wire{background:var(--card-2)}
/* .v is NOT in the card recipe above. setup.html's .verdicts .v (0,2,0)
   already declares its own ground, hairline, 4px status stripe, radius and
   padding, and .v.good/.mid/.bad colour that stripe at the same specificity.
   Putting .v in the recipe - at any specificity - hands theme.css the last
   word on `border`, which resets the stripe to a 1px --line hairline and the
   ground to white, and the verdict loses the one mark that carries its state.
   Leave .v to the page. */

/* ---------- TWO-LETTER CLASS COLLISIONS ----------
   .t and .v are each used for two unrelated things in this codebase, and the
   card recipe cannot tell them apart:
     .v   setup's verdict CARD  (setup.html .verdicts .v)   -> is a card
          analytics' bar VALUE  (analytics.html .bar .v)    -> is not
          setup's key/value pair (.kvs .v)                  -> is not
          -- so .v is left out of the recipe entirely; see the note above.
     .t   analytics' KPI tile / bugs' count tile            -> is a card
          calendar's time label (.row .t)                   -> is not
          demos' chase-banner text column (.chase .t)       -> is not
   .v is out of the recipe, which kills that half at source. The two
   .t consumers are scoped one level deeper here and given their ground back;
   without this, /calendar draws a white bordered 3px box around every "14:01"
   and /demos draws one inside the chase banner. */
.row .t,.chase .t{background:none;border:none;border-radius:0;padding:0}
/* .chase .t b is a wrapping sentence, not a display number: the KPI rule above
   catches it via `.t b` and hands it Roman at line-height:1, so lines touch. */
.chase .t b{font-family:var(--font-display);line-height:var(--lh-snug)}

.card:hover,.stat:hover,.day:hover,.opt:hover,.t:hover,.pill-btn:hover{transform:none}
/* ⚠ HOVER DARKENS THE EDGE, IT DOES NOT YELLOW IT. Every hover in this app used
   to swap the border to --accent, and #ffc310 is 1.41:1 on this ground against
   the resting edge's 3.14:1 — so pointing at a control made its outline fainter
   than leaving it alone, which is backwards. --accent-ink is the same yellow's
   dark voice (5.47:1 here, 6.25:1 on a card): still unmistakably the accent,
   but the boundary gets STRONGER under the cursor. 22 rules across 7 files. */
a.stat:hover,.pill-btn:hover,.pick:hover,.day:hover,.opt:hover{border-color:var(--accent-ink)}
/* .dial-btn:hover{transform:scale(1.05)} is the ONE exception and stays: it is
   the primary physical action of the app, so a press response is functional
   feedback rather than decoration. */

/* Menus and popovers take the stronger hairline in place of the deleted --e2. */
.more-menu{border-color:var(--line-2)}

/* ---------- SPEC TABLE — the corpus recipe, verbatim ----------
   The published pattern: the table sits on a #f2f0eb block (web value --well),
   rows separated by 1px WHITE rules, NO outer border, label cell Heavy
   charcoal, value cell Roman grey, both left-aligned.
   White rules on a warm grey block disappear INTO the block instead of drawing
   a grid — which is "separate blocks with tone and rules, not shadows" stated
   literally. Grey hairlines on white is what every framework ships; this is
   what says Safelift. (#ffffff is written as a literal here, not as a token,
   because the device is specifically a white RULE, not a surface.) */
table{width:100%; border-collapse:collapse; background:var(--well); border:none}
th{
  background:var(--well); text-align:left;
  border:none; border-bottom:1px solid #ffffff;
  font-family:var(--font-display); font-weight:normal;
  font-size:var(--t-micro); letter-spacing:var(--ls-caps); text-transform:uppercase;
  color:var(--accent-ink); padding:10px 14px;
}
td{
  border:none; border-bottom:1px solid #ffffff;
  font-family:var(--font); font-weight:normal;
  font-size:var(--t-md); color:var(--muted); padding:11px 14px;
}
td:first-child{font-family:var(--font-display); color:var(--ink)}
tr:last-child td{border-bottom:none}
tr:hover td{background:var(--bg-deep)}

/* table.mini is the compact variant and keeps its own rules at (0,1,2). */
table.mini{width:100%; border-collapse:collapse; font-size:var(--t-md); background:none}
table.mini th{padding:7px 10px; background:none; border-bottom:1px solid var(--line)}
table.mini td{padding:9px 10px; border-bottom:1px solid var(--line); color:var(--muted)}
table.mini td:first-child{color:var(--ink); font-family:var(--font-display)}
table.mini tr:last-child td{border-bottom:none}
table.mini tr:hover td{background:none}

/* ---------- KPI TILE / DISPLAY NUMBER ----------
   Roman, per the Thin substitution. The label under it inherits the eyebrow. */
.kpi b,.stat b,.t b,.t .n,.chase .n,.bigweeks b,.dnum b{
  display:block;
  font-family:var(--font);
  font-weight:normal;
  letter-spacing:0;
  line-height:1;
  font-variant-numeric:tabular-nums;
  color:var(--ink);
}

/* ---------- BUTTONS ----------
   PRIMARY is safelift.se's own published button: dark text on yellow, 3px. */
.dial-btn,.save-next,.send,.bug-send,.btn-primary,.mini-btn,.rc-done,.dial,
.rbtn.go,.acts button.fix,.filters button.on,.save,a.back,.tabs button.on{
  background:var(--accent);
  color:var(--on-accent);      /* #333333 — 7.86:1. NEVER #ffffff (1.61:1). */
  border:none; border-radius:var(--radius);
  font-family:var(--font-display); font-weight:normal;
  box-shadow:none;
}
.dial-btn:hover,.save-next:hover,.send:hover,.bug-send:hover,.mini-btn:hover,
.dial:hover,.rbtn.go:hover,.save:hover,a.back:hover{background:var(--accent-hover)}
.dial-btn{border-radius:50%}   /* the one circle */

/* DANGER — dark fill, white text. The end-call button's label was 2.42:1 on a
   red ground, read at speed mid-call; that was the single worst thing in the
   app. */
.end,.rbtn.stop,.flag,.mi-bad{
  background:var(--grad-danger);
  color:var(--on-solid);       /* 5.23:1 on #d2232a, 6.92:1 on #b01c22 */
  border:none; border-radius:var(--radius);
  font-family:var(--font-display); font-weight:normal;
  box-shadow:none;
}

/* POSITIVE SOLID */
.pick.yes,.callbtn{
  background:var(--grad-ok);
  color:var(--on-solid);       /* 5.35:1 on #1d7a45, 8.04:1 on #155c34 */
  border:none; border-radius:var(--radius);
  font-family:var(--font-display); font-weight:normal;
}

/* WARNING SOLID — the "this sounds like an answerphone" button on the live
   call screen. It is the ONLY place --warn-solid carries text (every other
   consumer paints a dot, a stripe or a border), and it was written
   color:var(--on-accent) back when --warn-solid was byte-identical to the
   yellow accent, where #333 was correct at 7.86:1. Moving --warn-solid off the
   accent to #8a5a00 to make "warning" distinguishable from "brand" drops that
   pairing to 2.13:1, so the ink has to move with it: #ffffff on #8a5a00 is
   5.93:1. Fixed here rather than in the page so the token change cannot ship a
   regression while it waits for a page pass. */
.vmhint button{color:var(--on-solid)}

/* SECONDARY — white ground, and a boundary that actually clears WCAG 1.4.11. */
.pill-btn,.bug-cancel,.edit-cancel,.ai-plan .fix,.bug-mic,.bug-btn,.acts button,
.filters button,.dispo button,.pick.no,.rbtn,.vbtns button,.cpy{
  background:var(--card);
  color:var(--muted);
  border:1px solid var(--control-edge);   /* 3.59:1 — a control needs an edge */
  border-radius:var(--radius);
  font-family:var(--font-display); font-weight:normal;
  box-shadow:none;
}
.pill-btn:hover,.acts button:hover,.filters button:hover,.rbtn:hover,
.vbtns button:hover{color:var(--ink); border-color:var(--accent-ink); background:var(--card)}

/* GHOST — no ground, no border. */
.x,.more-menu button,.pu-viewas button{
  background:none; border:none; border-radius:var(--radius);
  color:var(--muted); font-family:var(--font);
}
.more-menu button:hover{background:var(--well); color:var(--ink)}

/* ---------- INPUT ---------- */
input,select,textarea{
  background:#ffffff;
  color:var(--ink);
  border:1px solid var(--control-edge);  /* was --line-2 at 1.63:1 — below the
                                            3:1 floor for a control boundary.
                                            --line stays #dcdcd5 for card and
                                            table separators, which are
                                            decorative and correctly exempt. */
  border-radius:var(--radius);
  font-family:var(--font);
}
input::placeholder,textarea::placeholder{color:var(--faint)}
option{background:#ffffff; color:var(--ink)}

/* ---------- BADGE / CHIP — flat, square, no lozenges ----------
   The corpus has no capsules. Squared BY SELECTOR so --r-pill stays 999px for
   the scrollbar thumbs, dots, bars, tracks and meters that are genuinely round.
   Measured ground/ink pairs, all passing: --accent-soft+--accent-ink 5.80,
   --ok-soft+--ok 6.21, --warn-soft+--warn 5.49, --danger-soft+--danger 5.95,
   --info-soft+--info 6.54, --well+--faint 5.02. The one place a real yellow
   FILL is corpus-correct is a status chip carrying --on-accent on --accent,
   which .warmth.warm already does. */
.tag,.pill,.chip,.vtag,.req,.mi-bad,.chain-badge,.up-src,.why-card .src,.warmth,
.queue-tag,.flag{
  display:inline-block;
  border-radius:var(--radius);
  padding:3px 9px;
  font-family:var(--font-display); font-weight:normal;
  font-size:var(--t-micro);
  letter-spacing:var(--ls-caps);
  text-transform:uppercase;
  white-space:nowrap;
}

/* ---------- WARNING CALLOUT — the manuals' block plus a left border ----------
   Published recipe: an #f2f0eb block with a 4-6pt left border, yellow for notes
   and #d2232a for danger, charcoal heading and body. */
.note,.callout,.lc-bounce,.note-say,.banner{
  background:var(--well); border:none; border-left:5px solid var(--accent);
  border-radius:0; padding:12px 15px; color:var(--muted); font-size:var(--t-md);
}
.callout.danger,.lc-stop,.lc-stopfoot,.bad-note{
  background:var(--well); border:none; border-left:5px solid var(--danger-solid);
  border-radius:0; padding:13px 15px; color:var(--danger);
}
/* pre.raw printed a raw call transcript in --ghost on a SOLID YELLOW ground at
   11px mono — 3.33:1, and it is the one block a rep opens when a call has gone
   wrong. No Safelift brochure or manual sets a paragraph on yellow. Keep the
   yellow as a RULE and move the text to 9.02:1. */
pre.raw{
  background:var(--well); color:var(--muted);
  border-left:5px solid var(--accent);
  border-radius:0; padding:14px;
}

/* ---------- STATUS DOT ----------
   Four states, four distinguishable colours. .call and .mail_out used to paint
   the same, and a rep reads dot colour to tell "we phoned them" from "we
   mailed them". Fixed at the token (--warn-solid); restated here so this file
   owns it and followups.html's missing .note state is covered. */
.hdot,.live-dot,.wp-dot,.dot,.cdot,.bug-mic-dot{border-radius:50%; flex:none}
.hdot.call{background:var(--accent)}
.hdot.mail_out{background:var(--warn-solid)}
.hdot.mail_in{background:var(--ok-solid)}
.hdot.note{background:var(--ink)}

/* ============================================================================
   THE SHELL — safelift.se's dark masthead band (#222), wordmark left, active
   item yellow. Turned on its side, it is the sidebar.
   ========================================================================== */
.pu-side{
  position:fixed; left:0; top:0; bottom:0; width:var(--rail); z-index:60;
  background:var(--band); border:none; border-radius:0;
  box-shadow:none; padding:22px 12px; display:flex; flex-direction:column; gap:2px;
  overflow-y:auto;
}
.pu-brand{display:flex; align-items:center; gap:10px; text-decoration:none;
  padding:2px 8px 0; color:var(--band-ink)}
.pu-mark{
  width:28px; height:28px; border-radius:var(--radius); display:grid;
  place-items:center; background:var(--accent); color:var(--on-accent);
  flex:none;
}
.pu-mark svg{width:17px; height:17px; display:block}
.pu-name{font-family:var(--font-display); font-weight:normal; font-size:15px;
  letter-spacing:0; color:var(--band-ink)}
.pu-rule{height:1px; background:var(--band-rule); margin:18px 0 12px}

.pu-nav{display:flex; flex-direction:column; gap:1px}
.pu-item{
  display:flex; align-items:center; gap:11px; text-decoration:none;
  padding:10px 10px; border-radius:var(--radius); background:transparent;
  color:var(--band-muted); font-size:var(--t-md);
  transition:background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.pu-item .pu-ico{
  width:19px; height:19px; flex:none; border:none; border-radius:0;
  display:grid; place-items:center; line-height:1;
  background:transparent; color:var(--band-icon); box-shadow:none;
}
/* The icons are inline SVG drawn on a 24 box, taking currentColor, so the
   active item's yellow reaches the mark as well as the label. A font glyph
   could not do that reliably: it is whatever face the machine happens to own. */
.pu-item .pu-svg{width:19px; height:19px; display:block}
.pu-item:hover{background:var(--band-hover); color:var(--band-ink)}
/* ⛔ THE ONE LEGITIMATE YELLOW-AS-TEXT IN THE PRODUCT — 9.90:1 on #222, the
   site's own active-nav treatment, and in the collapsed 58px rail it is the
   ONLY indicator of which screen you are on. Keep it exactly. */
.pu-item.on{background:transparent; color:var(--accent); font-family:var(--font-display)}
.pu-item.on .pu-ico{color:var(--accent)}

/* The yellow dot on an unfinished Setup. Small, and it is the only thing in
   the navigation that changes state, so it reads as "something is waiting"
   rather than as decoration. It disappears with the menu item itself. */
.pu-item .pu-dot{
  width:6px; height:6px; border-radius:50%; background:var(--accent);
  margin-left:auto; flex:none;
}
@media (max-width:1500px){ .pu-item .pu-dot{position:absolute; margin:0; top:7px; right:7px}
  .pu-item{position:relative} }

/* The account line at the foot of the sidebar: who you are, and the way back
   into Setup once it has left the menu. */
.pu-acct{margin-top:auto; padding-top:14px; border-top:1px solid var(--band-rule)}
.pu-acct-who{
  font-family:var(--font-display); font-weight:normal; font-size:var(--t-micro);
  letter-spacing:var(--ls-caps); text-transform:uppercase;
  color:var(--band-faint); padding:0 10px 5px;
}
.pu-acct-link{
  display:block; padding:8px 10px; border-radius:var(--r-2);
  color:var(--band-muted); text-decoration:none; font-size:var(--t-sm);
}
.pu-acct-link:hover{background:var(--band-hover); color:var(--band-ink)}
.pu-acct-link.on{color:var(--accent)}
@media (max-width:1500px){
  .pu-acct-who{display:none}
  .pu-acct-link{text-align:center; padding:8px 4px; font-size:10px}
}

/* ⚠ --rail and this padding are ONE pair. They cannot be allowed to drift — it
   is the most likely single mistake in a masthead restyle. */
body.pu-shell{padding-left:var(--rail)}

@media (max-width:1500px){
  .pu-side{width:var(--rail-narrow); padding:22px 8px; align-items:center}
  .pu-name,.pu-rule{display:none}
  .pu-brand{justify-content:center; padding:0 0 16px}
  .pu-item{justify-content:center; padding:10px 6px}
  .pu-item .pu-label{display:none}
  body.pu-shell{padding-left:var(--rail-narrow)}
}
@media (max-width:900px){
  .pu-side{
    left:0; right:0; top:auto; bottom:0; width:auto; height:auto;
    flex-direction:row; border-top:1px solid var(--band-rule);
    padding:6px 8px; overflow-x:auto;
  }
  .pu-brand{display:none}
  .pu-nav{flex-direction:row; width:100%; justify-content:space-around}
  .pu-item{flex-direction:column; gap:3px; font-size:10px; padding:6px 8px}
  .pu-item .pu-label{display:block}
  body.pu-shell{padding-left:0; padding-bottom:66px}
}

/* ---------- view as a salesperson ---------- */
.pu-viewas{margin-top:auto; padding-top:14px; border-top:1px solid var(--band-rule);
  display:flex; flex-direction:column; gap:1px}
.pu-va-h{color:var(--band-faint); padding:0 10px 5px}
.pu-viewas button{
  display:flex; align-items:center; gap:6px; text-align:left; width:100%;
  background:transparent; border:none; border-radius:var(--radius);
  padding:9px 10px; color:var(--band-muted); font-family:var(--font);
  font-size:var(--t-sm); cursor:pointer;
}
.pu-viewas button:hover{background:var(--band-hover); color:var(--band-ink)}
.pu-viewas em{font-style:normal; font-size:var(--t-micro); color:var(--band-faint)}

/* ---------- THE YELLOW TAGLINE STRIP ----------
   The site's signature move: dark panel, full-width #ffc310 strip, dark Heavy
   UPPERCASE line. It already exists here as #viewbar.
   ⛔ Do not build a second one that competes with it, and do not add a second
   dark band above the content — the dark band role is taken by the sidebar. */
#viewbar{
  position:fixed; top:0; left:0; right:0; z-index:80;
  background:var(--accent); color:var(--on-accent);
  display:flex; align-items:center; justify-content:center; gap:14px;
  padding:9px 16px; font-size:12.5px; font-family:var(--font-display);
  font-weight:normal; letter-spacing:var(--ls-caps); text-transform:uppercase;
}
#viewbar b{color:var(--on-accent)}
#viewbar button{
  /* this ground was written #333 like the text on yellow above, so one string
     meant two different things and a change to either would have moved both */
  background:var(--ink); color:var(--on-solid); border:none;
  border-radius:var(--radius);
  padding:5px 13px; font-family:var(--font-display); font-size:11.5px;
  font-weight:normal; cursor:pointer; text-transform:none; letter-spacing:0;
}
#viewbar button:hover{background:var(--band-deep)}
#viewbar button:disabled{opacity:.6; cursor:default}
body.pu-viewing{padding-top:36px}

@media (max-width:1500px){
  .pu-viewas .pu-va-h{display:none}
  .pu-viewas button{justify-content:center; padding:8px 4px; font-size:10px}
  .pu-viewas em{display:none}
}

/* The header rule. It was a 4px yellow strip — the brochure's signature band,
   which at full width and full strength shouted over everything under it and
   made every page look like a printed cover. Here it is a hairline that just
   closes the header, with a short yellow segment at the left as the accent.
   ⚠ NO margin-bottom: on index and followups the .top is the auto row of a
   height:100% grid, and a margin there eats the content row. The pages are
   box-sizing:border-box with an explicit height, so this adds no height. */
.top{
  border-bottom:1px solid var(--line);
  position:relative;
}
.top::after{
  content:''; position:absolute; left:0; bottom:-1px;
  width:56px; height:2px; background:var(--accent);
}

/* ---------- report a problem ---------- */
.bug-btn{
  position:fixed; right:16px; bottom:16px; z-index:70;
  display:flex; align-items:center; gap:8px;
  padding:9px 14px; font-size:12.5px; cursor:pointer;
}
.bug-btn span{
  width:17px; height:17px; border-radius:2px; background:var(--accent);
  color:var(--on-accent); display:grid; place-items:center; font-size:11px;
  font-family:var(--font-display); flex:none;
}
.bug-btn:hover{color:var(--ink); border-color:var(--accent-ink)}
@media (max-width:900px){ .bug-btn{bottom:76px; right:12px} }

#bugwrap{position:fixed; inset:0; z-index:90; display:grid; place-items:center; padding:20px}
.bug-scrim{position:absolute; inset:0; background:var(--scrim)}
.bug-card{
  position:relative; background:var(--card); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:var(--e3);   /* a true modal — one of
                                             the three places --e3 is allowed */
  padding:26px; width:min(500px,94vw);
}
.bug-card h3{margin:0 0 6px; font-size:20px}
.bug-sub{margin:0 0 14px; font-size:var(--t-md); color:var(--muted); line-height:var(--lh-body)}
#bug-what{
  width:100%; min-height:110px; resize:vertical; padding:12px 14px;
  font-size:var(--t-lg); line-height:1.6;
}
.bug-foot{display:flex; justify-content:flex-end; gap:8px; margin-top:14px}
.bug-cancel{padding:10px 16px; font-size:var(--t-md)}
.bug-cancel:hover{background:var(--bg)}
.bug-send{padding:10px 20px; font-size:var(--t-md)}
.bug-send:disabled{opacity:.5; cursor:default}
.bug-done{font-size:var(--t-lg); color:var(--muted); line-height:var(--lh-body)}

/* ---------- talk to report ---------- */
.bug-row{display:flex; align-items:center; gap:10px; margin-bottom:10px}
.bug-mic{
  display:flex; align-items:center; gap:8px;
  padding:9px 15px; font-size:var(--t-md); color:var(--ink); cursor:pointer;
}
.bug-mic:hover{border-color:var(--accent-ink)}
.bug-mic.on{background:var(--danger-soft); border-color:var(--danger-line); color:var(--danger)}
.bug-mic:disabled{opacity:.5; cursor:default}
.bug-mic-dot{width:9px; height:9px; background:var(--accent)}
.bug-mic-dot.on{background:var(--danger); animation:bugpulse 1.1s ease-in-out infinite}
@keyframes bugpulse{0%,100%{opacity:1}50%{opacity:.25}}
.bug-live{font-size:12.5px; color:var(--muted)}
/* ⚠ Do not move any other @keyframes into this file without renaming per
   component: `pulse` is defined four times across the pages for four different
   intents, `blink`, `eq` and `rise` twice each. They never collide today
   because each page loads only its own block plus this one. */
@media (prefers-reduced-motion:reduce){ .bug-mic-dot.on{animation:none} }

/* ---------- callouts on the lead column ---------- */
.lc-stop{margin:0 0 12px; font-size:var(--t-md); font-family:var(--font-display)}
.lc-stop span{display:block; font-family:var(--font); font-size:var(--t-sm);
  margin-top:4px; color:var(--muted)}
.lc-stopfoot{font-size:13.5px; text-align:left; font-family:var(--font-display)}
.lc-bounce{margin:10px 0 4px; font-size:var(--t-sm)}
.lc-extra{margin:10px 0 4px; padding:14px 16px; border-radius:0;
  background:var(--well); border:none}
/* the spec table device, in miniature: white rules on the warm block */
.lc-extra .lx{display:flex; justify-content:space-between; gap:14px; padding:5px 0;
  font-size:13.5px; border-bottom:1px solid #ffffff}
.lc-extra .lx span{color:var(--muted)}
.lc-extra .lx b{text-align:right; color:var(--ink)}

/* ---------- call screen ---------- */
.warmth{padding:4px 11px}
.warmth.cold{background:var(--bg-deep); color:var(--muted)}
.warmth.warm{background:var(--accent); color:var(--on-accent)}

.why-card{margin-top:16px; background:var(--well); border:none;
  border-left:5px solid var(--accent); border-radius:0; padding:15px 17px}
.why-card p{margin:0; font-size:var(--t-lg); color:var(--ink); line-height:1.65;
  white-space:pre-line}
.why-card .src{margin-top:10px; font-size:10px; color:var(--on-accent);
  background:var(--accent); border-radius:2px; padding:3px 9px}
.why-card.thin p{font-size:13.5px; color:var(--muted)}

.up-why{margin-top:14px; padding-top:13px; border-top:1px solid var(--line);
  font-size:var(--t-md); line-height:1.6; color:var(--muted); text-align:left}
.up-why b{color:var(--ink); font-family:var(--font-display); font-weight:normal}
.up-src{font-size:10px; color:var(--on-accent);
  background:var(--accent); border-radius:2px; padding:2px 9px}

.brief{display:grid; gap:0; margin-bottom:6px}
.bpt{background:var(--well); border:none; border-bottom:1px solid #ffffff;
  border-radius:0; padding:12px 15px; font-size:var(--t-md); line-height:1.6;
  color:var(--muted)}
.brief-wait{font-size:var(--t-md); color:var(--muted); padding:8px 2px}
.intel h3.h3-gap{margin-top:22px; padding-top:18px; border-top:1px solid var(--line)}

.live-words{margin:10px 0 4px; border:none; background:var(--well);
  border-left:5px solid var(--line-2); border-radius:0; padding:12px 15px}
.live-words summary{cursor:pointer; font-size:var(--t-micro);
  letter-spacing:var(--ls-caps); text-transform:uppercase;
  font-family:var(--font-display); color:var(--faint)}
.live-words .lw-text{margin-top:8px; font-size:var(--t-md); line-height:1.65;
  white-space:pre-wrap; color:var(--ink)}

.ai-plan{margin:4px 0 10px; padding:15px 17px; border-radius:0;
  border:none; border-left:5px solid var(--accent); background:var(--well)}
.ai-plan .pl{font-size:var(--t-lg); margin-bottom:12px; color:var(--ink)}
.ai-plan .pc{display:flex; gap:8px; flex-wrap:wrap}
.ai-plan .fix{padding:8px 13px; font-size:var(--t-sm)}
.ai-plan .fix:hover{border-color:var(--accent-ink); color:var(--ink)}
.ai-plan .fix.danger{color:var(--danger); border-color:var(--danger)}
.ai-plan #ovr-at{margin-top:10px}

.outcomes.stop-row{margin-top:8px}
.oc.nocontact{border-color:var(--danger-line); background:var(--danger-soft);
  color:var(--danger)}
.oc.nocontact small{color:var(--danger)}

/* the pale-yellow decision block keeps its own ground — it is the corpus
   note-block, not a card */
.decision{background:var(--accent-soft); border:1px solid var(--accent-line);
  border-radius:var(--radius); box-shadow:none}

/* ---------- mail thread ----------
   ⛔ NEVER add a display property to .mailwrap. It is shown/hidden with the
   HTML hidden attribute; see the [hidden] guard at the top of this file. */
.mailwrap{max-width:1180px; margin:26px auto 60px; padding:0 18px}
.mailwrap h3{margin:0 0 12px}
.mail-item{padding:16px 18px; margin-bottom:10px}
.mail-item.them{border-left:5px solid var(--accent)}
.mi-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:7px}
.mi-sub{font-size:var(--t-lg); color:var(--ink)}
.mi-date{margin-left:auto; font-size:var(--t-xs); color:var(--faint)}
.mi-bad{font-size:var(--t-micro); border-radius:2px; padding:3px 8px}
.mi-body{font-size:var(--t-md); line-height:var(--lh-body); color:var(--muted);
  white-space:pre-wrap; max-height:200px; overflow:auto}

/* ---------- one mark, not six ----------
   Every page used to draw its own gradient orb (a blue one on the dialler, a
   different one on the calendar), so two unrelated marks sat on screen at once.
   !important #3 of 3: scar tissue from exactly that conflict. Nine page-level
   .orb rules still exist at (0,1,0); once they are deleted this file wins on
   load order at equal specificity and the flag comes out. Delete the nine
   FIRST, then this — not the other way round. */
.orb{
  width:34px; height:34px; border-radius:var(--radius); flex:0 0 auto;
  display:grid !important; place-items:center;
  background:var(--accent); color:var(--on-accent);
  font-size:var(--t-xl); line-height:1; box-shadow:none;
}
.logo{color:var(--ink); text-decoration:none}
.logo small{color:var(--accent-ink)}

/* ---------- analytics: personal first, company second ---------- */
.say{margin:0 0 10px; font-size:16px; line-height:var(--lh-body); color:var(--muted)}
.say b{color:var(--ink)}
.say:last-child{margin-bottom:0}
.muted-say{font-size:14.5px}
.note-say{font-size:13.5px; padding:11px 14px; margin-top:12px}

details.deep{margin-top:30px; border-top:1px solid var(--line-2); padding-top:6px}
.deepsum{
  cursor:pointer; list-style:none; padding:15px 2px; font-size:var(--t-md);
  color:var(--muted); display:flex; align-items:center; gap:10px;
}
.deepsum::-webkit-details-marker{display:none}
.deepsum::before{
  content:'+'; width:22px; height:22px; flex:none; border-radius:var(--radius);
  background:var(--accent); color:var(--on-accent);
  display:grid; place-items:center; font-family:var(--font-display); font-size:var(--t-md);
}
details.deep[open] .deepsum::before{content:'\2212'}
.deepsum:hover{color:var(--ink)}
.deepin{padding-top:4px}

/* ---------- an unassigned lead is a FAULT, not a state ---------- */
.bad-note b{color:var(--danger)}
.bad-note select{margin:0 6px; padding:5px 8px; font-size:var(--t-sm)}
.mini-btn{padding:6px 13px; font-size:var(--t-sm)}
.mini-btn:disabled{opacity:.55; cursor:default}
#fix-msg{color:var(--danger); font-size:var(--t-sm)}

/* ---------- /team: manage-a-salesperson editor ---------- */
#editbox{position:fixed; inset:0; z-index:90; place-items:center; padding:20px}
.edit-scrim{position:absolute; inset:0; background:var(--scrim)}
.edit-card{
  position:relative; background:var(--card); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:var(--e3);   /* true modal */
  padding:24px; width:min(460px,94vw);
  max-height:90vh; overflow:auto;
}
.edit-card h3{margin:0 0 16px; font-size:19px}
.edit-card label{display:block; margin-bottom:12px}
.edit-card label span{display:block; font-size:var(--t-xs); color:var(--muted); margin-bottom:5px}
.edit-card input{width:100%; padding:9px 11px; font-size:var(--t-md)}
.edit-foot{display:flex; align-items:center; gap:8px; margin-top:8px}
.edit-off{
  /* Destructive controls carry the full red on the edge, not the pale chip
     tint: --danger-line is 1.52:1 on white, which is not an edge, it is a
     suggestion of one. --danger is 5.95:1. */
  background:var(--card); border:1px solid var(--danger); color:var(--danger);
  border-radius:var(--radius); padding:8px 13px; font-family:var(--font);
  font-size:var(--t-sm); cursor:pointer;
}
.edit-off:hover{background:var(--danger-soft)}
.edit-cancel{padding:8px 15px; font-size:var(--t-md)}
.edit-cancel:hover{background:var(--bg)}
