/* ==========================================================================
   Digital Pratik public site design system.

   The card language is the proven DBC v5 / SattvaRig system, ported intact
   (opaque cards built from three cheap static layers, a lit hairline, a plate
   ring, a dot-matrix canvas, one filled card per section). Only the brand
   tokens and the type scale changed. Do not restructure the components.

   BRAND: blue (ported from dubai-dbc-v7 on DP's instruction, 2026-07-29,
   replacing Gold-Noir). Near-black paper + electric blue #5E92E8 on dark (the default),
   white paper + black ink on light, with the SAME yellow filled card in both
   so the brand signature survives the theme flip.

   THEME RULE (standing order 2026-07-26): dark AND light, always. Dark is the
   default. Light genuinely adjusts, it is not an inversion. Yellow is
   unreadable as TEXT on white, so in light mode accent TEXT drops to black and
   yellow stays a fill and a highlight only.

   TYPE (standing order 2026-07-26): Plus Jakarta Sans everywhere, JetBrains
   Mono for numbers and small caps labels, Caveat for handwritten winks. Base
   type is lifted to a comfortable reading size, this is a blog and people
   read it for four minutes at a time.

   PHONE FIRST. Effectively all traffic is on phones. Every rule here is
   written to be right at 375px before it is right on a desktop. The phone-only
   overrides live in ONE block at the very bottom, headed PHONE EXPERIENCE, so
   they are easy to find and tune.

   Smoothness rule: animate transform and opacity only. Respect reduced motion.
   ========================================================================== */

:root{
  /* BLUE THEME, ported from dubai-dbc-v7 on DP's instruction 2026-07-29.
     This replaced Gold-Noir. The whole palette lives in these two blocks, so
     reverting is a matter of putting the old blocks back, not a rewrite.
     Dark is still THE DEFAULT here (DBC runs light by default; this site does
     not, and that difference is deliberate). */
  --bg-0:#070707;
  --bg-1:#0D0D0D;
  --paper:#161616;
  /* cards are OPAQUE. Translucent glass over a gradient hazes everything. */
  --glass:#161616;
  --glass-hi:#1D1D1D;
  --card-grad:linear-gradient(168deg,#1A1A1A 0%,#141414 100%);
  --card-edge:rgba(255,255,255,.08);      /* the lit hairline on the top edge */
  --plate:rgba(94,146,232,.05);           /* the faint plate stacked behind a card */
  --dots:rgba(255,255,255,.07);           /* canvas dot matrix */
  --bar:rgba(7,7,7,.84);                  /* the sticky top bar, the one translucent surface */
  --line:rgba(255,255,255,.11);
  --line-strong:rgba(94,146,232,.32);
  --line-soft:rgba(255,255,255,.06);
  /* ink */
  --text-1:#F8F8F8;
  --text-2:#A5ACB7;
  /* --text-3 carries dates, read times, captions and the footer. It was raised
     off the DBC value to clear AA against the CARD colour, which is the paler
     surface and therefore the worse case. Do not drop it back. */
  --text-3:#8A8F98;
  /* ONE blue family. On dark the accent runs full blue with WHITE ink on
     buttons, which is the flip from Gold-Noir, where the ink was black. */
  --accent:#5E92E8;
  --accent-ink:#FFFFFF;   /* ink that sits ON the accent (buttons) */
  --accent-2:#8FB3EE;
  --accent-deep:#2E6BD3;
  --accent-glow:rgba(46,107,211,.4);
  /* THE BUTTON SURFACE IS NOT --accent, and that split is load bearing.
     --accent #5E92E8 is tuned to be read as LINK TEXT against near-black, where
     it measures about 7:1. Used as a button fill under white lettering it
     measures 3.11:1, which is below the AA minimum, and the sweep caught it on
     every primary button on every page. The deeper blue under white ink
     measures 5.04:1 and is identical in both themes, exactly like the filled
     card. */
  --btn-bg:#2E6BD3;
  --btn-ink:#FFFFFF;
  --accent-soft:rgba(94,146,232,.13);
  --success:#2FBF71;
  --success-soft:rgba(47,191,113,.1);
  --warn:#E3A008;
  --warn-soft:rgba(227,160,8,.12);
  --danger:#F2555C;
  /* the secondary voice: a lighter steel blue of the same family */
  --gold:#8FB3EE;
  --gold-soft:rgba(143,179,238,.1);
  --gold-line:rgba(143,179,238,.38);
  --field-bg:rgba(255,255,255,.05);
  /* the filled card: ONE per section. Deep navy with WHITE ink. Under
     Gold-Noir this was a yellow panel with black ink; the ink flipped with the
     panel and every rule that assumed dark ink on it had to follow. */
  --fill:linear-gradient(158deg,#1E4A96 0%,#133875 52%,#0B2450 100%);
  --fill-glow:0 34px 76px -34px rgba(19,56,117,.7);
  --fill-ink:#FFFFFF;
  --fill-muted:rgba(226,240,255,.78);
  --fill-line:rgba(255,255,255,.18);
  --grad:linear-gradient(100deg,#5E92E8,#8FB3EE);
  /* motion */
  --t-fast:170ms;
  --t-med:340ms;
  --t-slow:680ms;
  --ease:cubic-bezier(0.16,1,0.3,1);
  --radius:20px;
  --radius-sm:14px;
  --shadow:0 22px 50px -20px rgba(0,0,0,.65);
  --shadow-soft:0 14px 34px -18px rgba(0,0,0,.72);
  --shadow-lg:0 34px 74px -26px rgba(0,0,0,.85);
}
[data-theme="light"]{
  /* White air, near-black ink, one electric blue. Unlike the yellow it
     replaced, this blue IS readable as text on white, so --accent stays blue
     here instead of collapsing to black the way Gold-Noir had to. */
  --bg-0:#FFFFFF;
  --bg-1:#F5F5F8;
  --paper:#FFFFFF;
  --glass:#FFFFFF;
  --glass-hi:#F5F7FB;
  --card-grad:linear-gradient(168deg,#FFFFFF 0%,#FFFFFF 100%);
  /* a white highlight is invisible on a white card, so the lit edge becomes a
     faint steel hairline. Same job: it crisps the top of the card. */
  --card-edge:rgba(39,67,103,.14);
  --plate:rgba(39,67,103,.04);
  --dots:rgba(39,67,103,.1);
  --bar:rgba(255,255,255,.88);
  --line:rgba(28,36,49,.12);
  --line-strong:rgba(28,36,49,.26);
  --line-soft:rgba(28,36,49,.07);
  --text-1:#1C1C1C;
  --text-2:#55606E;
  /* raised off the DBC #8B94A1 for the same AA reason as the dark block */
  --text-3:#6E7784;
  --accent:#2E6BD3;
  --accent-ink:#FFFFFF;
  --accent-2:#6FA0EA;
  --accent-deep:#1C4FA8;
  --accent-glow:rgba(46,107,211,.3);
  --btn-bg:#2E6BD3;
  --btn-ink:#FFFFFF;
  --accent-soft:rgba(46,107,211,.08);
  --success:#12A150;
  --success-soft:rgba(18,161,80,.08);
  --warn:#D98A00;
  --warn-soft:rgba(217,138,0,.1);
  --danger:#E5484D;
  --gold:#3D5E93;
  --gold-soft:rgba(61,94,147,.08);
  --gold-line:rgba(61,94,147,.3);
  --field-bg:#FFFFFF;
  /* the filled card stays IDENTICAL in both themes, which is the one rule
     carried over from Gold-Noir unchanged. Only the colour of the panel
     changed, not the principle. */
  --fill:linear-gradient(158deg,#1E4A96 0%,#133875 52%,#0B2450 100%);
  --fill-glow:0 30px 66px -30px rgba(19,56,117,.5);
  --fill-ink:#FFFFFF;
  --fill-muted:rgba(230,242,255,.85);
  --fill-line:rgba(255,255,255,.22);
  /* THE LIGHT GRADIENT IS TIGHTER THAN DBC'S ON PURPOSE. Headings use
     background-clip:text, so the GRADIENT IS THE INK and its palest stop is
     what a reader actually has to read. DBC's #6FA0EA measures 2.66:1 on white,
     under the 3:1 large-text minimum, and the sweep flagged every gradient
     heading on every light page. #4E86DB measures 3.65:1 and still reads as a
     blue gradient. */
  --grad:linear-gradient(100deg,#2E6BD3,#4E86DB);
  --shadow:0 24px 56px -22px rgba(39,67,103,.3);
  --shadow-soft:0 14px 36px -20px rgba(39,67,103,.24);
  --shadow-lg:0 32px 70px -26px rgba(39,67,103,.36);
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  background:var(--bg-0);
  color:var(--text-1);
  font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
  font-size:18.4px;
  font-feature-settings:'tnum';
  line-height:1.6;
  letter-spacing:-.004em;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  min-height:100vh;
}
img,svg{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font-family:inherit;cursor:pointer}
::selection{background:var(--accent);color:var(--accent-ink)}

/* ---------- the card recipe ----------
   Three cheap static layers, no glass blur:
   1. a soft 168deg gradient fill
   2. a 1px lit hairline across the top edge, inset from both sides
   3. a faint plate ring stacked behind the card
   Everything that is a card in this stylesheet uses .surface-card. */
.surface-card,
.gcard,.stat,.answer-card,.table-wrap,.faq,.form-card,.info-card,.quote,
.est-card,.band,.calc-shell,.step,.tnode .t-card,.gpt-side,.gpt-main{
  background:var(--card-grad);
  border:1px solid var(--line);
  border-radius:var(--radius);
  box-shadow:0 0 0 6px var(--plate),var(--shadow-soft);
  position:relative;
}
.surface-card::before,
.gcard::before,.stat::before,.answer-card::before,.table-wrap::before,.faq::before,
.form-card::before,.info-card::before,.quote::before,.est-card::before,.band::before,
.calc-shell::before,.step::before,.tnode .t-card::before,.gpt-side::before,.gpt-main::before{
  content:"";position:absolute;top:0;left:22px;right:22px;height:1px;
  background:linear-gradient(90deg,transparent,var(--card-edge),transparent);
  pointer-events:none;z-index:2;
}
/* nested tiles sit inside a section, so they skip the plate ring: stacking
   plates everywhere turns a grid into mush */
.step,.tnode .t-card,.checklist li,.opt,.answer-grid .ans,.result-rows,.gpt-side{
  box-shadow:var(--shadow-soft);
  border-radius:var(--radius-sm);
}

/* THE FILLED CARD. One per section. A solid blue panel carrying that
   section's single most important message. */
.fill-card{
  background:var(--fill);
  border-color:transparent;
  color:var(--fill-ink);
  box-shadow:0 0 0 6px var(--plate),var(--fill-glow);
  overflow:hidden;
}
/* the inner light: a soft top-left highlight plus the same dot matrix as the
   canvas, so it reads as a lit panel and not a flat blue box */
.fill-card::before{
  content:"";position:absolute;inset:0;top:0;left:0;right:0;height:auto;
  background:
    radial-gradient(ellipse 96% 58% at 50% -16%,rgba(255,255,255,.16),transparent 62%),
    radial-gradient(circle,rgba(255,255,255,.10) 1px,transparent 1px);
  background-size:auto,22px 22px;
  opacity:.9;pointer-events:none;
}
.fill-card>*{position:relative;z-index:1}
.fill-card h2,.fill-card h3,.fill-card strong,.fill-card b{color:var(--fill-ink)}
.fill-card p,.fill-card small{color:var(--fill-muted)}
.fill-card .sec-kicker{color:var(--fill-muted)}
.fill-card .sec-kicker::before{background:var(--fill-muted)}
.fill-card h2 em,.fill-card h1 em{background:none;-webkit-text-fill-color:var(--fill-muted);color:var(--fill-muted)}
/* a button on a blue card flips to white, a blue button on blue disappears */
.fill-card .btn{background:rgba(255,255,255,.12);border-color:var(--fill-line);color:var(--fill-ink)}
.fill-card .btn:hover{background:rgba(255,255,255,.2);border-color:rgba(255,255,255,.34);color:var(--fill-ink)}
.fill-card .btn.primary,.fill-card .btn.primary:hover,
.fill-card .btn.gold,.fill-card .btn.gold:hover,
.fill-card .btn-primary,.fill-card .btn-primary:hover{
  background:#FFFFFF;color:#133875;border-color:transparent;
  box-shadow:0 12px 30px -14px rgba(0,0,0,.5);
}

/* ---------- ambient field ----------
   DP, 2026-07-26: ALL the background gradients are gone. The old field had two
   drifting orbs, corner radials and a vertical bg-1 to bg-0 wash, and the wash
   read as a dirty grey fade across the top and bottom of every page, worst in
   light mode where it went beige over the text. Flat paper now. The only thing
   left is the faint dot matrix, which is texture rather than a gradient.
   Do not reintroduce a background gradient here. */
.ambient{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  background:var(--bg-0);
}
[data-theme="light"] .ambient{background:var(--bg-0)}
/* the orbs are retired. The markup still ships the two divs so no page needs
   editing, they simply render nothing. */
.ambient .orb{display:none}
.ambient .grid{position:absolute;inset:0;
  background-image:radial-gradient(var(--dots) 1px,transparent 1px);
  background-size:26px 26px;opacity:.55;
  mask-image:radial-gradient(ellipse 95% 80% at 50% 0%,black 10%,transparent 80%);
  -webkit-mask-image:radial-gradient(ellipse 95% 80% at 50% 0%,black 10%,transparent 80%)}

/* ---------- layout ---------- */
.wrap{width:min(1180px,calc(100% - 32px));margin:0 auto}
main{position:relative;z-index:1}
section{padding:56px 0;position:relative}
@media (min-width:721px){
  .wrap{width:min(1180px,calc(100% - 48px))}
  section{padding:64px 0}
}

/* ---------- top command bar ---------- */
.topbar{position:sticky;top:0;z-index:60;background:var(--bar);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border-bottom:1px solid var(--line)}
.topbar-inner{display:flex;align-items:center;gap:14px;padding:11px 0}
.brand{display:flex;align-items:center;gap:11px;min-width:0;flex:none}
/* the real DBC lockup (brand guidelines 2022): mark + Arabic + English in
   one horizontal artwork. SattvaRig runs a text wordmark instead, green on
   light surfaces and white on dark ones, so the dark theme whitens the same
   file with a filter. Height-driven so it scales cleanly on any screen. */
.brand img{height:40px;width:auto;border-radius:0;flex:none}
html:not([data-theme="light"]) .brand img{filter:brightness(0) invert(1)}
@media (max-width:720px){.brand img{height:31px}}
.brand .b-txt{display:flex;flex-direction:column;line-height:1.15;min-width:0}
/* the mark swaps with the theme: white art on dark, navy art on light,
   exactly the guidelines' logo usage rules */
.logo-on-dark{display:block}
.logo-on-light{display:none}
[data-theme="light"] .logo-on-dark{display:none}
[data-theme="light"] .logo-on-light{display:block}
.brand .b-name{font-weight:700;font-size:16.7px;letter-spacing:-.02em;white-space:nowrap}
.brand .b-sub{font-family:"JetBrains Mono",monospace;font-size:10.4px;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--text-3);white-space:nowrap}
.navlinks{display:flex;align-items:center;gap:4px;margin-left:auto}
.navlinks a{font-size:15.5px;font-weight:600;color:var(--text-2);padding:8px 12px;border-radius:100px;border:1px solid transparent;transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease);white-space:nowrap}
.navlinks a:hover{color:var(--accent);border-color:var(--line)}
.navlinks a.on{color:var(--text-1);border-color:var(--line);background:var(--glass)}
.topbar-cta{display:flex;align-items:center;gap:9px;flex:none}
.topbar .btn{white-space:nowrap}
.theme-toggle{appearance:none;width:40px;height:40px;border-radius:50%;border:1px solid var(--line);background:var(--glass);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.theme-toggle:hover{transform:scale(1.08);border-color:var(--accent)}
.theme-toggle svg{width:17px;height:17px;color:var(--text-2)}
.theme-toggle:hover svg{color:var(--accent)}
.theme-toggle .i-moon{display:none}
[data-theme="light"] .theme-toggle .i-sun{display:none}
[data-theme="light"] .theme-toggle .i-moon{display:block}
.nav-toggle{display:none;appearance:none;width:40px;height:40px;border-radius:50%;border:1px solid var(--line);background:var(--glass);flex-direction:column;align-items:center;justify-content:center;gap:4px}
.nav-toggle span{display:block;width:16px;height:1.5px;background:var(--text-1);border-radius:2px;transition:transform var(--t-fast) var(--ease),opacity var(--t-fast) var(--ease)}
.nav-toggle.on span:nth-child(1){transform:translateY(5.5px) rotate(45deg)}
.nav-toggle.on span:nth-child(2){opacity:0}
.nav-toggle.on span:nth-child(3){transform:translateY(-5.5px) rotate(-45deg)}
/* tablet: the menu drops from the bar. Phone gets a bottom sheet instead,
   see PHONE EXPERIENCE at the bottom of this file. */
@media (max-width:1080px){
  /* solid panel, anchored to the bottom of the sticky bar. No backdrop-filter
     here: nesting one inside the bar's own filter reads as see-through. */
  .navlinks{position:absolute;top:100%;left:0;right:0;flex-direction:column;align-items:stretch;gap:2px;padding:14px 18px 20px;background:#0A0A0A;border-bottom:1px solid var(--line);box-shadow:var(--shadow);transform:translateY(-12px);opacity:0;pointer-events:none;transition:transform var(--t-med) var(--ease),opacity var(--t-med) var(--ease)}
  [data-theme="light"] .navlinks{background:#FFFFFF}
  .navlinks.open{transform:translateY(0);opacity:1;pointer-events:auto}
  .navlinks a{padding:12px 14px;font-size:16.7px}
  .nav-toggle{display:flex}
  .topbar-cta .btn.nav-quote{display:none}
}

/* ---------- buttons ---------- */
.btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  border:1px solid var(--line);background:var(--glass);color:var(--text-1);
  font-family:inherit;font-weight:600;font-size:15px;border-radius:100px;
  padding:12px 20px;min-height:46px;cursor:pointer;text-align:center;
  /* NOT nowrap: a long label ("Price my jurisdiction") then sets a 390px
     min-content floor on its grid track and pushes the whole page sideways at
     375px. Only the header bar, where wrapping looks untidy, keeps nowrap. */
  transition:transform var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease);
  box-shadow:var(--shadow-soft);-webkit-tap-highlight-color:transparent}
.btn:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}
.btn:active{transform:translateY(0) scale(.97)}
.btn .arrow{transition:transform var(--t-fast) var(--ease)}
.btn:hover .arrow{transform:translateX(3px)}
/* The accent flipped per theme (light blue on dark, navy on light), so the
   button ink flips with it: navy ink on the light-blue button, white ink on
   the navy button. --accent-ink carries that. */
.btn.primary{background:var(--btn-bg);color:var(--btn-ink);border-color:var(--btn-bg);box-shadow:0 12px 30px -10px var(--accent-glow)}
.btn.primary:hover{color:var(--btn-ink);transform:translateY(-2px);box-shadow:0 18px 42px -12px var(--accent-glow)}
/* gold is not a brand colour: the old gold CTA now rides the same brand pair */
.btn.gold{background:var(--gold);color:var(--accent-ink);border-color:var(--gold);box-shadow:0 10px 26px -10px var(--accent-glow)}
.btn.gold:hover{color:var(--accent-ink);transform:translateY(-2px)}
.btn.sm{font-size:14.4px;padding:9px 16px;min-height:40px}
.btn.lg{font-size:17.3px;padding:14px 26px;min-height:52px}

/* ---------- shared type ---------- */
h1,h2,h3,h4{font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;letter-spacing:-.03em;line-height:1.1}
/* v5: type reverted to the v3 face on DP's call 2026-07-22. Headings ride the
   body Inter (no serif), the hook word is Outfit light italic with
   the gradient clipped into the text. The brand palette stays as applied. */
h1 em,h2 em,h3 em,.it{
  font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;font-style:italic;font-weight:300;letter-spacing:-.02em;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.mono{font-family:"JetBrains Mono",monospace}
.num{font-family:"JetBrains Mono",monospace;font-variant-numeric:tabular-nums}
.eyebrow{display:inline-flex;align-items:center;gap:9px;font-family:"JetBrains Mono",monospace;font-size:12.1px;font-weight:500;letter-spacing:.2em;color:var(--accent);text-transform:uppercase;border:1px solid var(--line);border-radius:100px;padding:8px 18px;background:var(--glass);box-shadow:var(--shadow-soft)}
.eyebrow.gold{color:var(--gold);border-color:var(--gold-line)}
.eyebrow .dot{width:6px;height:6px;border-radius:50%;background:var(--success);animation:pulse-dot 2.2s var(--ease) infinite}
@keyframes pulse-dot{0%,100%{box-shadow:0 0 0 0 rgba(47,191,113,.45)}50%{box-shadow:0 0 0 7px transparent}}
/* the font strip: mono, uppercase, wide-tracked, with a leading rule */
.sec-kicker{font-family:"JetBrains Mono",monospace;font-size:12.1px;font-weight:500;letter-spacing:.2em;text-transform:uppercase;color:var(--accent);margin-bottom:12px;display:flex;align-items:center;gap:8px}
.sec-kicker::before{content:"";width:18px;height:1px;background:var(--accent);flex:none}
.sec-kicker.gold{color:var(--gold)}
.sec-kicker.gold::before{background:var(--gold)}
.sec-head{margin-bottom:28px;max-width:760px}
.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}
.sec-head.center .sec-kicker{justify-content:center}
.sec-head h2{font-size:clamp(29.9px,3.6vw,43.7px);font-weight:620;letter-spacing:-.032em;line-height:1.12;margin-bottom:12px}
.sec-head p{color:var(--text-2);font-size:17.3px}
.sec-head.center p{margin-left:auto;margin-right:auto}
@media (min-width:721px){.sec-head{margin-bottom:34px}}

/* ---------- reveal ---------- */
.reveal{opacity:0;transform:translateY(16px);transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease)}
.reveal.in{opacity:1;transform:translateY(0)}
.reveal.d1{transition-delay:.08s}.reveal.d2{transition-delay:.16s}.reveal.d3{transition-delay:.24s}.reveal.d4{transition-delay:.32s}

/* ---------- hero ---------- */
.hero{padding:36px 0 44px}
.hero-inner{display:grid;grid-template-columns:1fr;gap:30px;align-items:center}
.hero h1{font-size:clamp(36.8px,5.4vw,59.8px);font-weight:600;letter-spacing:-.035em;line-height:1.06;margin:20px 0 14px}
.hero .lead{color:var(--text-2);font-size:19px;max-width:560px}
.hero-ctas{display:flex;gap:11px;flex-wrap:wrap;margin-top:24px}
.hero-trust{display:flex;gap:9px;flex-wrap:wrap;margin-top:22px}
/* DIRECT children only. An unscoped `.hero-trust span` also matched the
   nested .chip-x tail, which then drew its own pill and produced a box
   inside a box. gap is 0 so the tail reads as one continuous line, and
   the dot carries its own right margin instead. */
.hero-trust > span{display:inline-flex;align-items:center;gap:0;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.06em;color:var(--text-2);border:1px solid var(--line);border-radius:100px;padding:7px 14px;background:var(--glass)}
.hero-trust i{width:5px;height:5px;border-radius:50%;background:var(--success);flex:none;margin-right:7px}
/* phone-only scroll cue between the hero copy and the snapshot card. Desktop
   shows both side by side, so there is nothing to hint at. */
.scroll-cue{display:none}
@keyframes cue-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(6px)}}
@media (min-width:961px){
  .hero{padding:64px 0 52px}
  .hero-inner{grid-template-columns:1.15fr .85fr;gap:44px}
}

/* the live estimate card: the home hero's ONE filled blue card */
.est-card{background:var(--fill);border-color:transparent;color:var(--fill-ink);
  box-shadow:0 0 0 6px var(--plate),var(--fill-glow);padding:22px 22px;overflow:hidden}
.est-card::before{content:"";position:absolute;inset:0;top:0;left:0;right:0;height:auto;
  background:
    radial-gradient(ellipse 70% 60% at 12% -10%,rgba(215,251,227,.34),transparent 62%),
    radial-gradient(circle,rgba(255,255,255,.10) 1px,transparent 1px);
  background-size:auto,22px 22px;opacity:.9;pointer-events:none}
.est-card>*{position:relative;z-index:1}
.est-card .scan{position:absolute;top:0;bottom:0;width:120px;pointer-events:none;background:linear-gradient(100deg,transparent,rgba(255,255,255,.16),transparent);transform:translateX(-160px);opacity:0;z-index:1}
.est-card.in .scan{animation:scan-sweep 1.3s var(--ease) .2s 1 both}
@keyframes scan-sweep{0%{opacity:1;transform:translateX(-160px)}100%{opacity:0;transform:translateX(760px)}}
.est-top{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--fill-line)}
.est-top strong{font-size:17.3px;font-weight:650;color:var(--fill-ink)}
.est-badge{font-family:"JetBrains Mono",monospace;font-size:10.4px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:#FFFFFF;border:1px solid var(--fill-line);background:rgba(255,255,255,.14);border-radius:100px;padding:5px 10px;display:inline-flex;align-items:center;gap:6px}
.est-badge i{width:5px;height:5px;border-radius:50%;background:#B9F2D3;animation:pulse-dot 2s var(--ease) infinite}
.est-row{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:9px 0;font-size:15.5px}
.est-row span:first-child{color:var(--fill-muted)}
.est-row span:last-child{font-weight:650;color:var(--fill-ink);text-align:right}
.est-total{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin-top:14px;padding-top:15px;border-top:1px solid var(--fill-line)}
.est-total span{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--fill-muted)}
.est-total strong{font-family:"JetBrains Mono",monospace;font-variant-numeric:tabular-nums;font-size:31px;font-weight:700;color:var(--fill-ink);letter-spacing:-.02em}
.est-foot{margin-top:14px;font-size:13.2px;color:var(--fill-muted);line-height:1.5}

/* ---------- marquee ---------- */
.marquee{position:relative;z-index:1;overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--card-grad);padding:12px 0}
.marquee-track{display:flex;gap:0;width:max-content;animation:march 38s linear infinite;will-change:transform}
.marquee-track span{font-family:"JetBrains Mono",monospace;font-size:12.1px;letter-spacing:.18em;text-transform:uppercase;color:var(--text-3);padding:0 26px;position:relative;white-space:nowrap}
.marquee-track span::after{content:"";position:absolute;right:0;top:50%;width:4px;height:4px;border-radius:50%;background:var(--accent);opacity:.5;transform:translateY(-50%)}
@keyframes march{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ---------- inner page hero ---------- */
.page-hero{padding:30px 0 34px}
.page-hero h1{font-size:clamp(32px,4.6vw,52px);font-weight:600;letter-spacing:-.035em;line-height:1.08;margin:16px 0 14px;max-width:900px}
.page-hero .lead{color:var(--text-2);font-size:18.4px;max-width:760px}
.page-hero .hero-ctas{margin-top:24px}
@media (min-width:721px){.page-hero{padding:48px 0 40px}}
/* founder portrait in the page hero (DP, 2026-07-23) */
.founder-photo{width:132px;height:132px;border-radius:50%;object-fit:cover;border:2px solid var(--line-strong);box-shadow:var(--shadow-soft),0 0 0 6px var(--accent-glow);display:block;margin-bottom:18px}

/* ---- founder hero: copy on the left, a big portrait on the right. Stacks on
       a phone with the photo under the copy, so the headline still lands
       first. The source photo is 400x400, so the frame is capped at 400 and
       never upscaled into mush. ---- */
.founder-hero-in{display:grid;gap:28px;align-items:center}
.founder-copy{min-width:0}
.founder-shot{margin:0;position:relative;width:100%;max-width:400px;justify-self:center}
.founder-shot img{display:block;width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;
  border-radius:var(--radius);border:1px solid var(--line);
  box-shadow:var(--shadow),0 0 0 8px var(--plate)}
/* the name plate sits ON the photo, so it wears its own dark glass in both
   themes rather than following the page tokens */
.founder-shot figcaption{position:absolute;left:13px;right:13px;bottom:13px;
  display:flex;flex-direction:column;gap:3px;padding:12px 15px;border-radius:14px;
  background:rgba(6,20,10,.6);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid rgba(255,255,255,.15)}
.founder-shot figcaption strong{font-size:15.5px;font-weight:700;letter-spacing:-.012em;color:#fff}
.founder-shot figcaption span{font-family:"JetBrains Mono",monospace;font-size:10.2px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--accent-deep)}
@media (min-width:901px){
  .founder-hero-in{grid-template-columns:minmax(0,1fr) 400px;gap:60px}
  .founder-shot{justify-self:end}
}

/* ---------- breadcrumbs ---------- */
.crumbs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:16px 0 0;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3)}
.crumbs a{color:var(--text-3);transition:color var(--t-fast) var(--ease)}
.crumbs a:hover{color:var(--accent)}
.crumbs span[aria-current]{color:var(--accent)}
.crumbs .sep{opacity:.5}

/* Grid items default to min-width:auto, so one wide child (the price table,
   whose AED column is nowrap) sets a min-content floor and pushes the whole
   page sideways at 375px. min-width:0 caps the track and lets the table
   scroll inside its own .table-scroll instead. */
.split>*,.grid-2>*,.grid-3>*,.grid-4>*,.steps>*,.track>*,.stats>*,
.answer-grid>*,.opt-grid>*,.form-grid>*,.gpt-wrap>*{min-width:0}

/* ---------- split ---------- */
.split{display:grid;grid-template-columns:1fr;gap:26px;align-items:start}
@media (min-width:901px){.split{grid-template-columns:1fr 1fr;gap:34px}}

/* ---------- checklist ---------- */
.checklist{list-style:none;display:flex;flex-direction:column;gap:11px;margin-top:18px}
.checklist li{display:flex;gap:12px;align-items:flex-start;background:var(--card-grad);border:1px solid var(--line);padding:15px 16px;font-size:15.5px;color:var(--text-2);line-height:1.6;transition:border-color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.checklist li:hover{border-color:var(--accent);transform:translateX(2px)}
.checklist li strong{color:var(--text-1);font-weight:700}
.checklist .check{flex:none;width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff;background:var(--accent);margin-top:2px}

/* ---------- caution note (honest limits, not a scare box) ---------- */
.caution{margin-top:22px;display:flex;gap:14px;align-items:flex-start;background:linear-gradient(150deg,var(--warn-soft),transparent 62%),var(--card-grad);border:1px solid rgba(227,160,8,.34);border-radius:var(--radius-sm);padding:17px 18px}
.caution .c-ico{flex:none;width:36px;height:36px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:17px;background:var(--warn-soft);border:1px solid rgba(227,160,8,.34)}
.caution .c-t{font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--warn);margin-bottom:6px}
.caution p{font-size:15.5px;color:var(--text-2);line-height:1.6}
.caution p a{color:var(--accent);font-weight:700}

/* ---------- price table ---------- */
.table-wrap{overflow:hidden}
.table-wrap .tw-head{padding:16px 20px;border-bottom:1px solid var(--line);font-family:"JetBrains Mono",monospace;font-size:12.1px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.table-scroll{overflow-x:auto}
.price-table{width:100%;border-collapse:collapse;min-width:340px}
.price-table th{text-align:left;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);font-weight:600;padding:14px 18px;border-bottom:1px solid var(--line)}
.price-table th:last-child,.price-table td:last-child{text-align:right}
.price-table td{padding:14px 18px;font-size:15.5px;color:var(--text-2);border-bottom:1px solid var(--line-soft)}
.price-table td:last-child{font-family:"JetBrains Mono",monospace;font-size:14.4px;color:var(--text-1);font-weight:500;white-space:nowrap}
.price-table tr:last-child td{border-bottom:0}
/* opt-in total row. Do not key this off :last-child, most tables end on a normal row. */
.price-table tr.total td{background:var(--accent-soft);color:var(--text-1);font-weight:700}
.price-table tr.total td:last-child{color:var(--gold)}

/* ---------- numbered steps grid ---------- */
.steps{display:grid;grid-template-columns:1fr;gap:12px}
.step{padding:18px 18px;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.step:hover{transform:translateY(-3px);border-color:var(--accent)}
.step .n{display:inline-block;font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.16em;color:var(--accent);margin-bottom:9px}
.step h3{font-size:18.4px;font-weight:650;margin-bottom:6px;letter-spacing:-.02em}
.step p{font-size:14.4px;color:var(--text-2);line-height:1.55}
@media (min-width:561px){.steps,.steps.cols-5,.steps.cols-3{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1001px){
  .steps{grid-template-columns:repeat(4,minmax(0,1fr))}
  .steps.cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}
  .steps.cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
}

/* ---------- answer-first block (SEO / answer-engine surface) ---------- */
.answer-sec{padding-top:48px}
.answer-card{padding:24px 20px}
.answer-lead{font-size:17.8px;line-height:1.72;color:var(--text-2);max-width:900px}
/* short answers are one sentence per paragraph (DP, 2026-07-25), so consecutive
   leads need breathing room or they read as one block again */
.answer-lead+.answer-lead{margin-top:14px}
.answer-lead strong{color:var(--text-1);font-weight:700}
.answer-grid{display:grid;grid-template-columns:1fr;gap:11px;margin-top:22px}
.answer-grid .ans{background:var(--glass-hi);border:1px solid var(--line);padding:15px 16px}
.answer-grid dt{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:6px}
.answer-grid dd{font-size:15.5px;font-weight:650;color:var(--text-1);line-height:1.45}
.answer-note{margin-top:20px;padding-top:16px;border-top:1px solid var(--line-soft);font-size:14.4px;color:var(--text-3);line-height:1.6}
@media (min-width:421px){.answer-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:721px){.answer-sec{padding-top:64px}.answer-card{padding:30px 32px}.answer-lead{font-size:19px}}
@media (min-width:1001px){.answer-grid{grid-template-columns:repeat(4,minmax(0,1fr))}}

/* ---------- cards ---------- */
.grid-2,.grid-3,.grid-4{display:grid;grid-template-columns:1fr;gap:14px}
@media (min-width:621px){.grid-3,.grid-4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:821px){.grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:961px){.grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}}

.gcard{padding:22px 22px 20px;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),box-shadow var(--t-med) var(--ease);display:flex;flex-direction:column}
.gcard:hover{transform:translateY(-3px);border-color:var(--line-strong);box-shadow:0 0 0 6px var(--plate),var(--shadow-lg)}
.gcard .g-ico{width:46px;height:46px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-size:21px;background:var(--accent-soft);border:1px solid var(--line);margin-bottom:14px}
.gcard .g-ico.gold{background:var(--gold-soft);border-color:var(--gold-line)}
.gcard .g-ico.cyan{background:rgba(94,146,232,.12)}
.gcard h3{font-size:21.8px;font-weight:650;letter-spacing:-.025em;margin-bottom:7px;line-height:1.2}
.gcard p{font-size:15.5px;color:var(--text-2);line-height:1.6}
.gcard .g-link{margin-top:auto;padding-top:16px;font-family:"JetBrains Mono",monospace;font-size:12.1px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);display:inline-flex;align-items:center;gap:7px}
.gcard .g-link .arrow{transition:transform var(--t-fast) var(--ease)}
.gcard:hover .g-link .arrow{transform:translateX(3px)}
.gcard .g-price{display:inline-block;margin-top:12px;font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;border-radius:100px;padding:5px 11px;color:var(--gold);border:1px solid var(--gold-line);background:var(--gold-soft)}
/* the section's one filled card, opt in per section with class="gcard fill-card" */
.gcard.fill-card .g-ico{background:rgba(255,255,255,.14);border-color:var(--fill-line)}
.gcard.fill-card .g-link{color:var(--fill-muted)}
.gcard.fill-card .g-price{color:#FFFFFF;border-color:var(--fill-line);background:rgba(255,255,255,.14)}

/* ---------- stats ---------- */
.stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.stat{padding:22px 16px;text-align:center;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.stat:hover{transform:translateY(-3px);border-color:var(--line-strong)}
.stat .num{font-family:"JetBrains Mono",monospace;font-variant-numeric:tabular-nums;font-size:clamp(32px,4vw,46px);font-weight:700;line-height:1.05;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat .label{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);margin-top:9px;line-height:1.5}
/* the stats row's one filled card */
.stat.fill-card .num{background:none;-webkit-text-fill-color:var(--fill-ink);color:var(--fill-ink)}
.stat.fill-card .label{color:var(--fill-muted)}
@media (min-width:961px){.stats{grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}}

/* ---------- process track ---------- */
.track{position:relative;display:grid;grid-template-columns:1fr;gap:14px}
.track .tline{display:none}
.tnode{position:relative;z-index:1;display:flex;flex-direction:column;opacity:.4;transform:translateY(8px);transition:opacity var(--t-slow) var(--ease),transform var(--t-slow) var(--ease)}
.tnode.lit{opacity:1;transform:translateY(0)}
.tnode .t-pin{width:46px;height:46px;margin:0 auto 13px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:18px;background:var(--glass-hi);border:2px solid var(--line);transition:border-color var(--t-med) var(--ease),box-shadow var(--t-med) var(--ease)}
.tnode.lit .t-pin{border-color:var(--accent);box-shadow:0 0 0 6px var(--accent-glow),0 0 24px var(--accent-glow)}
/* flex:1, not height:100%: the pin above the card sits inside the same grid
   cell, so a 100% tall card overflowed the cell by the pin's height and the
   last step landed on top of the stats row on phones (DP, 2026-07-23) */
.tnode .t-card{padding:16px 16px;flex:1}
.tnode.lit .t-card{border-color:var(--line-strong)}
.tnode .t-step{font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin-bottom:6px}
.tnode .t-t{font-weight:650;font-size:18.4px;line-height:1.25;margin-bottom:6px;letter-spacing:-.02em}
.tnode .t-d{font-size:14.4px;color:var(--text-2);line-height:1.55}
@media (min-width:561px){.track{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1001px){
  .track{grid-template-columns:repeat(5,minmax(0,1fr))}
  .track .tline{display:block;position:absolute;top:22px;left:6%;right:6%;height:2px;background:var(--line-soft);border-radius:2px;z-index:0}
  .track .tline .tfill{display:block;height:100%;width:0%;border-radius:2px;background:var(--grad);box-shadow:0 0 12px var(--accent-glow);transition:width 1.8s var(--ease)}
}

/* ---------- CTA band: the filled blue panel that closes a page ---------- */
.band{padding:34px 22px;text-align:center;overflow:hidden;
  background:var(--fill);border-color:transparent;color:var(--fill-ink);
  box-shadow:0 0 0 6px var(--plate),var(--fill-glow)}
.band::before{content:"";position:absolute;inset:0;top:0;left:0;right:0;height:auto;
  background:
    radial-gradient(ellipse 70% 60% at 12% -10%,rgba(215,251,227,.34),transparent 62%),
    radial-gradient(circle,rgba(255,255,255,.10) 1px,transparent 1px);
  background-size:auto,22px 22px;opacity:.9;pointer-events:none}
.band>*{position:relative;z-index:1}
.band h2{font-size:clamp(27.6px,3.4vw,41.4px);font-weight:620;letter-spacing:-.03em;line-height:1.14;margin-bottom:12px;color:var(--fill-ink)}
.band h2 em{background:none;-webkit-text-fill-color:var(--fill-muted);color:var(--fill-muted)}
.band p{color:var(--fill-muted);font-size:17.3px;max-width:620px;margin:0 auto}
.band .sec-kicker{color:var(--fill-muted);justify-content:center}
.band .sec-kicker::before{background:var(--fill-muted)}
.band .hero-ctas{justify-content:center}
.band .btn{background:rgba(255,255,255,.12);border-color:var(--fill-line);color:var(--fill-ink)}
.band .btn:hover{background:rgba(255,255,255,.2);border-color:rgba(255,255,255,.34);color:var(--fill-ink)}
.band .btn.primary,.band .btn.primary:hover,.band .btn.gold,.band .btn.gold:hover{
  background:#FFFFFF;color:#133875;border-color:transparent;box-shadow:0 12px 30px -14px rgba(0,0,0,.5)}
/* the gold band stays a money panel, not a second blue one: gold trim on the
   normal card surface, so a page never shows two filled blue cards in a row */
.band.gold{background:linear-gradient(150deg,var(--gold-soft),transparent 62%),var(--card-grad);
  border-color:var(--gold-line);color:var(--text-1);box-shadow:0 0 0 6px var(--plate),var(--shadow-soft)}
.band.gold::before{background:none}
.band.gold h2{color:var(--text-1)}
.band.gold h2 em{background:var(--grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.band.gold p{color:var(--text-2)}
.band.gold .sec-kicker{color:var(--gold)}
.band.gold .sec-kicker::before{background:var(--gold)}
.band.gold .btn{background:var(--glass);border-color:var(--line);color:var(--text-1)}
.band.gold .btn:hover{border-color:var(--accent);color:var(--accent)}
.band.gold .btn.gold,.band.gold .btn.gold:hover{background:var(--gold);border-color:var(--gold);color:var(--accent-ink)}
@media (min-width:621px){.band{padding:48px 40px}}

/* ---------- testimonials ---------- */
.quote{padding:22px;display:flex;flex-direction:column;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.quote:hover{transform:translateY(-3px);border-color:var(--gold-line)}
.quote .stars{color:var(--gold);letter-spacing:.16em;font-size:14.4px;margin-bottom:12px}
.quote p{font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;font-style:italic;font-weight:300;font-size:20px;line-height:1.45;color:var(--text-1);letter-spacing:-.02em}
.quote .who{display:flex;align-items:center;gap:11px;margin-top:auto;padding-top:18px}
.quote .avatar{width:40px;height:40px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff;background:conic-gradient(from 40deg,var(--accent),var(--accent-2),var(--accent))}
.quote .avatar.gold{background:conic-gradient(from 40deg,var(--gold),var(--accent-deep),var(--gold));color:#0A0A00}
.quote .who strong{display:block;font-size:15.5px;font-weight:700}
.quote .who small{display:block;font-family:"JetBrains Mono",monospace;font-size:10.4px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);margin-top:2px}

/* ---------- FAQ ---------- */
.faq{max-width:820px;margin:0 auto;overflow:hidden}
.faq-item{border-bottom:1px solid var(--line-soft)}
.faq-item:last-child{border-bottom:0}
.faq-q{appearance:none;width:100%;display:flex;align-items:center;gap:16px;text-align:left;background:transparent;border:0;color:var(--text-1);font-size:17.3px;font-weight:650;line-height:1.4;letter-spacing:-.02em;padding:18px 20px;min-height:60px;transition:color var(--t-fast) var(--ease)}
.faq-q:hover{color:var(--accent)}
.faq-q .plus{margin-left:auto;flex:none;width:26px;height:26px;border-radius:50%;border:1px solid var(--line);display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:400;color:var(--accent);transition:transform var(--t-med) var(--ease)}
.faq-q[aria-expanded="true"] .plus{transform:rotate(45deg)}
.faq-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--t-med) var(--ease)}
.faq-q[aria-expanded="true"]+.faq-a{grid-template-rows:1fr}
.faq-a>div{overflow:hidden}
.faq-a p{padding:0 20px 20px;font-size:16px;color:var(--text-2);line-height:1.65}
.faq-a p a{color:var(--accent);font-weight:700}
@media (min-width:721px){.faq-q{padding:19px 24px}.faq-a p{padding:0 24px 20px}}

/* ---------- footer ---------- */
/* THE FOOTER, ported from dubai-dbc-v7 on DP's instruction 2026-07-29.
   It is a deep navy slab that ignores the theme: it is identical in dark and
   light, the same way the filled card is, so the page always lands on the same
   note. Because the slab is always dark, everything inside it is written in
   fixed light ink rather than theme tokens, or it would go black on navy the
   moment somebody switched to light. */
.site-foot{position:relative;z-index:1;overflow:hidden;border-top:none;
  background:linear-gradient(168deg,#173F80 0%,#123268 42%,#0C2149 100%);
  color:#EAF1FF;padding:52px 0 26px}
/* the cursor-reactive dash field, drawn by assets/ui.js. Decorative only. */
.foot-fx{position:absolute;inset:0;width:100%;height:100%;display:block;
  pointer-events:none;z-index:0;opacity:.85}
.foot-inner{position:relative;z-index:1}
.site-foot .brand .wm,.site-foot p,.site-foot li a{color:#EAF1FF}
.site-foot h4{color:#8FB3EE}
.site-foot li a{color:rgba(234,241,255,.78)}
.site-foot li a:hover{color:#FFFFFF}
.foot-bottom{border-top-color:rgba(234,241,255,.16);color:rgba(234,241,255,.55)}
.foot-bottom a{color:inherit}
.foot-bottom a:hover{color:#FFFFFF}
.foot-grid{display:grid;grid-template-columns:1fr;gap:26px}
.foot-brand p{font-size:15.5px;color:rgba(234,241,255,.72);line-height:1.65;margin-top:14px;max-width:340px}
.site-foot h4{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;color:#8FB3EE;margin-bottom:12px}
.site-foot ul{list-style:none;display:flex;flex-direction:column;gap:2px}
.site-foot li a{font-size:15.5px;color:rgba(234,241,255,.78);display:flex;align-items:center;min-height:44px;transition:color var(--t-fast) var(--ease)}
.site-foot li a:hover{color:#FFFFFF}
.foot-bottom{display:flex;flex-direction:column;gap:8px;margin-top:32px;padding-top:20px;border-top:1px solid rgba(234,241,255,.16);font-family:"JetBrains Mono",monospace;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:rgba(234,241,255,.62)}
@media (min-width:521px){.foot-grid{grid-template-columns:1fr 1fr;gap:28px}}
@media (min-width:721px){
  .site-foot{padding:56px 0 28px}
  .foot-bottom{flex-direction:row;justify-content:space-between;flex-wrap:wrap;gap:14px}
  .site-foot ul{gap:8px}
  .site-foot li a{min-height:0;display:block}
}
@media (min-width:861px){.foot-grid{grid-template-columns:1.6fr 1fr 1fr 1fr;gap:36px}}

/* =========================================================================
   DBC GPT, an APP not a page.
   DP, 2026-07-22: the old version was a tall marketing page. On a phone you
   landed on a wall of topic buttons, and as soon as you scrolled the chat box
   went up off the screen. It now behaves like a chat app: the shell is exactly
   one viewport tall, only the transcript scrolls, and the composer never moves.
   On a phone the topic list is a bottom sheet behind a Topics button instead
   of a column you have to scroll past.
   ========================================================================= */

/* the chat shell is viewport height minus the page chrome above it, so the
   composer sits on the bottom edge and stays there while the log scrolls */
/* --gpt-chrome is the no-JS fallback. gpt.js measures the real distance from
   the top of the viewport and sets the height exactly, so the composer is on
   screen whatever the headline wraps to. */
.gpt-section{--gpt-chrome:250px}
.gpt-wrap{display:grid;grid-template-columns:1fr;gap:16px;align-items:stretch;
  height:calc(100dvh - var(--gpt-chrome));min-height:400px}
@media (min-width:1001px){
  .gpt-wrap{grid-template-columns:280px minmax(0,1fr)}
}
/* the header above the app stays compact: this is a tool, not a landing page */
.gpt-section{padding-top:0}
.gpt-page-hero{padding:18px 0 14px}
.gpt-page-hero h1{font-size:clamp(25px,3.2vw,36px);margin:10px 0 8px}
.gpt-page-hero .lead{font-size:16.7px}

.gpt-side{padding:16px 14px;display:flex;flex-direction:column;min-height:0;
  overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
.gpt-side::-webkit-scrollbar{width:7px}
.gpt-side::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px}
.gpt-side h3{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin-bottom:9px}
.gpt-side .gs-group{margin-bottom:18px}
.gpt-side .gs-group:last-child{margin-bottom:0}
.gs-sheet-head{display:none}
.gpt-topic{display:flex;align-items:center;gap:9px;width:100%;text-align:left;appearance:none;background:transparent;border:1px solid transparent;border-radius:11px;padding:10px;color:var(--text-2);font-family:inherit;font-size:15.5px;font-weight:600;line-height:1.35;cursor:pointer;transition:all var(--t-fast) var(--ease);min-height:44px}
.gpt-topic:hover{border-color:var(--line);background:var(--glass-hi);color:var(--accent)}
.gpt-topic .gt-ico{flex:none;font-size:16px}

/* the main column: header pinned, log scrolls, composer pinned */
.gpt-main{display:flex;flex-direction:column;overflow:hidden;min-height:0}
.gpt-head{display:flex;align-items:center;gap:11px;padding:13px 18px;border-bottom:1px solid var(--line);flex:none;position:relative;z-index:2}
.gpt-head .gh-dot{width:8px;height:8px;border-radius:50%;background:var(--success);flex:none;animation:pulse-dot 2.2s var(--ease) infinite}
.gpt-head .gh-t{font-weight:650;font-size:17.3px;letter-spacing:-.02em}
.gpt-head .gh-s{font-family:"JetBrains Mono",monospace;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3)}
.gpt-head .gh-topics{display:none}
.gpt-head .gh-new{margin-left:auto}

/* the transcript is the only thing on this page that scrolls */
.gpt-log{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:22px 18px 8px;display:flex;flex-direction:column;gap:18px;scroll-behavior:smooth}
.gpt-log::-webkit-scrollbar{width:8px}
.gpt-log::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:99px}
.gpt-msg{display:flex;gap:12px;animation:rise .4s var(--ease) both;max-width:760px;width:100%}
.gpt-msg .gm-av{flex:none;width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;color:#fff;background:conic-gradient(from 40deg,var(--accent),var(--accent-2),var(--accent))}
.gpt-msg.me .gm-av{background:var(--glass-hi);border:1px solid var(--line);color:var(--text-2)}
.gpt-msg .gm-body{flex:1;min-width:0;font-size:16.7px;line-height:1.68;color:var(--text-1);padding-top:3px}
.gpt-msg .gm-body p{margin-bottom:11px}
.gpt-msg .gm-body p:last-child{margin-bottom:0}
.gpt-msg .gm-body a{color:var(--accent);font-weight:700;text-decoration:underline;text-underline-offset:2px}
.gpt-msg .gm-body strong{color:var(--text-1);font-weight:700}
/* the visitor's own turn reads as a bubble, the way a chat app looks */
.gpt-msg.me{align-self:flex-end;flex-direction:row-reverse;max-width:620px}
.gpt-msg.me .gm-body{background:var(--accent-soft);border:1px solid var(--line);border-radius:16px 16px 4px 16px;padding:11px 15px;color:var(--text-1);font-weight:500}
.gpt-err{border:1px solid rgba(242,85,92,.4);background:rgba(242,85,92,.08);border-radius:var(--radius-sm);padding:13px 15px;font-size:15.5px;color:var(--text-2);line-height:1.6}
.gpt-err b{color:var(--danger)}
.gpt-typing{display:inline-flex;gap:4px;align-items:center;padding-top:8px}
.gpt-typing i{width:6px;height:6px;border-radius:50%;background:var(--accent);opacity:.4;animation:blink 1.3s var(--ease) infinite}
.gpt-typing i:nth-child(2){animation-delay:.18s}
.gpt-typing i:nth-child(3){animation-delay:.36s}
@keyframes blink{0%,100%{opacity:.25;transform:translateY(0)}50%{opacity:1;transform:translateY(-3px)}}

/* the suggestion chips sit directly above the composer and scroll sideways,
   so people can see there are things to ask without a wall of buttons */
.gpt-starters{flex:none;padding:10px 18px 0;display:flex;gap:8px;overflow-x:auto;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.gpt-starters::-webkit-scrollbar{display:none}
.gpt-starters button{appearance:none;flex:none;white-space:nowrap;border:1px solid var(--line);background:var(--glass-hi);color:var(--text-2);font-family:inherit;font-weight:600;font-size:14.4px;border-radius:100px;padding:9px 15px;cursor:pointer;transition:all var(--t-fast) var(--ease);min-height:42px}
.gpt-starters button:hover{border-color:var(--accent);color:var(--accent)}

/* the composer: one rounded field, always on screen */
.gpt-form{flex:none;padding:12px 18px 6px;display:flex;gap:10px;align-items:flex-end}
.gpt-form textarea{flex:1;appearance:none;background:var(--field-bg);border:1px solid var(--line);border-radius:22px;outline:0;color:var(--text-1);font-family:inherit;font-size:16.7px;padding:13px 18px;resize:none;max-height:130px;line-height:1.5;transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.gpt-form textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.gpt-form textarea::placeholder{color:var(--text-3)}
.gpt-send{appearance:none;flex:none;width:46px;height:46px;border-radius:50%;border:1px solid var(--accent);background:var(--accent);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--t-fast) var(--ease);box-shadow:0 6px 16px -4px var(--accent-glow)}
.gpt-send:hover:not(:disabled){transform:translateY(-2px)}
.gpt-send:disabled{opacity:.4;cursor:not-allowed;box-shadow:none}
.gpt-note{flex:none;padding:4px 18px 12px;font-size:12.5px;color:var(--text-3);line-height:1.5;text-align:center}


/* ---------- proof strip: authority and free zone logos under the hero ---------- */
.proof-row{display:flex;flex-wrap:wrap;gap:10px;justify-content:center;align-items:stretch}
.proof-row .pl{background:#FFFFFF;border:1px solid var(--line);border-radius:14px;padding:10px 18px;display:flex;align-items:center;justify-content:center;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.proof-row .pl:hover{transform:translateY(-2px);border-color:var(--line-strong)}
.proof-row .pl img{height:30px;width:auto;max-width:150px;object-fit:contain;display:block}
.proof-note{text-align:center;font-family:"JetBrains Mono",monospace;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);margin-top:14px}
@media (max-width:720px){.proof-row .pl{padding:8px 14px}.proof-row .pl img{height:24px;max-width:120px}}

/* ---------- footer payment methods row ---------- */
.pay-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pay-row span{background:#FFFFFF;border:1px solid var(--line-soft);border-radius:6px;padding:3px 8px;display:inline-flex;align-items:center}
.pay-row img{height:18px;width:auto;display:block}

/* ---------- FAQ encyclopedia ---------- */
.kb-search{position:relative;max-width:640px;margin:0 auto}
.kb-search input{width:100%;appearance:none;background:var(--card-grad);border:1px solid var(--line);border-radius:100px;outline:0;color:var(--text-1);font-family:inherit;font-size:16.7px;font-weight:500;padding:15px 52px 15px 22px;box-shadow:var(--shadow-soft);transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.kb-search input:focus{border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-glow)}
.kb-search input::placeholder{color:var(--text-3);font-weight:450}
.kb-search .kb-ico{position:absolute;right:20px;top:50%;transform:translateY(-50%);color:var(--text-3);pointer-events:none;display:flex}
.kb-count{text-align:center;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);margin-top:14px}
.kb-count b{color:var(--accent)}
/* the category row scrolls sideways inside itself, it never wraps */
.kb-cats{display:flex;gap:8px;margin:24px 0 8px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding-bottom:2px}
.kb-cats::-webkit-scrollbar{display:none}
.kb-cats button{appearance:none;flex:none;display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line);background:var(--card-grad);color:var(--text-2);font-family:inherit;font-weight:600;font-size:14.4px;border-radius:100px;padding:10px 18px;cursor:pointer;white-space:nowrap;transition:all var(--t-fast) var(--ease);min-height:44px}
.kb-cats button:hover{border-color:var(--accent);color:var(--accent)}
.kb-cats button.on{border-color:var(--accent);color:var(--text-1);box-shadow:0 6px 18px -6px var(--accent-glow)}
.kb-cats button .kb-n{font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--text-3)}
.kb-cats button.on .kb-n{color:var(--accent)}
@media (min-width:721px){.kb-cats{justify-content:center;flex-wrap:wrap;overflow:visible;margin:26px 0 8px}.kb-cats button{flex:0 0 auto}}
.kb-group{margin-top:38px;scroll-margin-top:88px}
.kb-group-head{display:flex;align-items:flex-start;gap:14px;margin-bottom:16px;padding-bottom:14px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.kb-group-head .kb-gi{flex:none;width:46px;height:46px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-size:21px;background:var(--accent-soft);border:1px solid var(--line)}
.kb-group-head h3{font-size:21.8px;font-weight:650;letter-spacing:-.025em;line-height:1.25}
.kb-group-head p{font-size:15.5px;color:var(--text-2);line-height:1.55;margin-top:3px}
.kb-group-head .kb-gn{flex:none;font-family:"JetBrains Mono",monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);border:1px solid var(--line);border-radius:100px;padding:5px 12px;white-space:nowrap}
@media (min-width:721px){.kb-group-head{flex-wrap:nowrap}.kb-group-head .kb-gn{margin-left:auto}}
.kb-empty{text-align:center;padding:48px 20px;color:var(--text-2)}
.kb-empty b{display:block;font-size:19px;color:var(--text-1);margin-bottom:8px}
.kb-hit{background:rgba(94,146,232,.34);border-radius:3px;padding:0 2px;color:var(--text-1)}

/* screen readers and crawlers get the heading, sighted users do not need it twice */
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- forms ---------- */
.form-card{padding:22px 18px}
/* pair fields two to a row: it turns a six line block into three.
   align-items:end so a label that wraps to two lines ("Phone (with country
   code)") does not push its input below its neighbour's. */
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:end}
.form-grid .field.full{grid-column:1/-1}
.field label{display:block;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-3);margin-bottom:7px}
.field input,.field select,.field textarea{width:100%;appearance:none;background:var(--field-bg);border:1px solid var(--line);border-radius:12px;outline:0;color:var(--text-1);font-family:inherit;font-size:16.7px;font-weight:500;padding:13px 14px;transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.field input::placeholder,.field textarea::placeholder{color:var(--text-3);font-weight:450}
.field textarea{resize:vertical;min-height:96px;line-height:1.55}
.field select{cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234ADE80' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 13px center;background-size:14px;padding-right:38px}
[data-theme="light"] .field select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='0A0A0A' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")}
.field .note{font-size:13.8px;color:var(--text-3);margin-top:10px;line-height:1.5}
.form-ok{display:none;padding:24px 22px;border-radius:var(--radius);background:var(--success-soft);border:1px solid rgba(47,191,113,.42)}
.form-ok.show{display:block;animation:rise .5s var(--ease) both}
.form-ok strong{font-size:18.4px;font-weight:700;color:var(--success)}
.form-ok p{color:var(--text-2);font-size:15.5px;margin-top:7px;line-height:1.6}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
@media (min-width:621px){.form-card{padding:26px 26px 24px}.form-grid{gap:14px}}

/* ---------- contact info cards ---------- */
.info-card{display:block;padding:20px;margin-bottom:12px;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.info-card:hover{transform:translateY(-3px);border-color:var(--line-strong)}
.info-card .g-ico{width:44px;height:44px;border-radius:14px;display:flex;align-items:center;justify-content:center;font-size:20px;background:var(--accent-soft);border:1px solid var(--line);margin-bottom:13px}
.info-card .g-ico.wa{background:rgba(37,211,102,.12);border-color:rgba(37,211,102,.4)}
.info-card h3{font-size:18.4px;font-weight:650;margin-bottom:6px;letter-spacing:-.02em}
.info-card p{font-size:15.5px;color:var(--text-2);line-height:1.6}
.info-card .g-link{display:inline-flex;align-items:center;gap:7px;margin-top:12px;font-family:"JetBrains Mono",monospace;font-size:12.1px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}

/* =========================================================================
   Cost calculator UI. The classes are exactly what assets/calculator.js
   emits, so the pricing logic and markup are untouched. Do not rename these.
   ========================================================================= */
.calc-shell{overflow:hidden}
.calc-head{padding:16px 18px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
.calc-head .title{font-weight:650;font-size:17.3px;display:flex;align-items:center;gap:10px;letter-spacing:-.02em}
.calc-head .title .pulse-dot{width:8px;height:8px;border-radius:50%;background:var(--success);flex:none;animation:pulse-dot 2.2s var(--ease) infinite}
.calc-progress{display:flex;align-items:center;gap:10px;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--text-3)}
.calc-bar{width:110px;height:6px;border-radius:100px;background:rgba(255,255,255,.08);overflow:hidden}
[data-theme="light"] .calc-bar{background:rgba(15,23,42,.08)}
.calc-bar i{display:block;height:100%;border-radius:100px;background:var(--grad);transform-origin:left;transform:scaleX(.2);transition:transform .6s var(--ease)}
.calc-xp{font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.1em;color:var(--gold);background:var(--gold-soft);border:1px solid var(--gold-line);padding:5px 12px;border-radius:100px}
.calc-xp.bump{animation:xp-bump .5s var(--ease)}
@keyframes xp-bump{0%,100%{transform:scale(1)}40%{transform:scale(1.18)}}
.calc-body{padding:26px 18px 30px;min-height:400px;position:relative}
.calc-q{font-size:clamp(21.8px,2.6vw,29.9px);font-weight:650;letter-spacing:-.03em;line-height:1.2;margin-bottom:8px}
.calc-sub{color:var(--text-2);font-size:16px;margin-bottom:22px}
.opt-grid,.opt-grid.three{display:grid;grid-template-columns:1fr;gap:11px}
@media (min-width:761px){.opt-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.opt-grid.three{grid-template-columns:repeat(3,minmax(0,1fr))}}
.opt{appearance:none;text-align:left;background:var(--card-grad);border:1px solid var(--line);border-radius:var(--radius-sm);padding:16px 17px;cursor:pointer;color:var(--text-1);font-family:inherit;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease);position:relative;min-height:56px}
.opt:hover{transform:translateY(-3px);border-color:var(--accent)}
.opt.selected{border-color:var(--accent);box-shadow:0 6px 18px -6px var(--accent-glow)}
.opt.selected::after{content:"";position:absolute;top:12px;right:12px;width:8px;height:8px;border-radius:50%;background:var(--accent)}
.opt .opt-emoji{font-size:22px;display:block;margin-bottom:9px}
.opt strong{display:block;font-size:16.7px;font-weight:650;margin-bottom:4px;letter-spacing:-.02em}
.opt small{color:var(--text-2);font-size:14.4px;line-height:1.5;display:block}
.stepper{display:flex;align-items:center;justify-content:center;gap:24px;padding:26px 0}
.stepper button{appearance:none;width:52px;height:52px;border-radius:50%;border:1px solid var(--line);background:var(--glass-hi);color:var(--text-1);font-size:22px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.stepper button:hover{transform:scale(1.08);border-color:var(--accent);color:var(--accent)}
.stepper button:active{transform:scale(.94)}
.stepper .count{font-family:"JetBrains Mono",monospace;font-variant-numeric:tabular-nums;font-size:52px;font-weight:700;min-width:90px;text-align:center;letter-spacing:-.03em;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.stepper .count.tick{animation:xp-bump .35s var(--ease)}
.calc-nav{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:26px}
.calc-back{appearance:none;background:none;border:0;color:var(--text-3);font-family:inherit;font-weight:600;font-size:15.5px;display:inline-flex;gap:8px;align-items:center;cursor:pointer;min-height:44px;transition:color var(--t-fast) var(--ease)}
.calc-back:hover{color:var(--accent)}
.calc-back[disabled]{opacity:0;pointer-events:none}
.calc-result{text-align:center}
.result-badge{display:inline-flex;align-items:center;gap:8px;padding:7px 17px;border-radius:100px;background:var(--gold-soft);border:1px solid var(--gold-line);color:var(--gold);font-family:"JetBrains Mono",monospace;font-weight:600;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;margin-bottom:20px}
.result-total{font-family:"JetBrains Mono",monospace;font-variant-numeric:tabular-nums;font-size:clamp(40px,6vw,64px);font-weight:700;letter-spacing:-.03em;line-height:1;margin:8px 0 6px;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.result-total .cur{font-size:.42em;vertical-align:super;margin-right:6px;-webkit-text-fill-color:var(--text-3)}
.result-note{color:var(--text-3);font-size:14.4px;margin-bottom:24px}
.result-rows{max-width:470px;margin:0 auto 24px;text-align:left;background:var(--glass-hi);border:1px solid var(--line);padding:6px 18px}
.result-rows .rr{display:flex;justify-content:space-between;gap:16px;padding:12px 0;border-bottom:1px solid var(--line-soft);font-size:15.5px;opacity:0;transform:translateY(12px)}
.result-rows .rr:last-child{border-bottom:0}
.result-rows .rr.show{animation:rr-in .5s var(--ease) forwards}
@keyframes rr-in{to{opacity:1;transform:translateY(0)}}
.result-rows .rr span:first-child{color:var(--text-2)}
.result-rows .rr span:last-child{font-family:"JetBrains Mono",monospace;font-weight:600;color:var(--text-1);white-space:nowrap}
.result-ctas{display:flex;gap:11px;justify-content:center;flex-wrap:wrap}
.calc-result details{max-width:470px;margin:0 auto 24px;text-align:left;background:var(--glass-hi);border:1px solid var(--line);border-radius:var(--radius-sm);padding:14px 18px}
.calc-result details summary{cursor:pointer;font-weight:650;font-size:15.5px;color:var(--text-1);list-style:none;min-height:32px}
.calc-result details summary::-webkit-details-marker{display:none}
.calc-result details ul{list-style:none;padding:12px 0 4px;display:grid;gap:8px;color:var(--text-2);font-size:14.4px;line-height:1.5}
@media (min-width:621px){.calc-head{padding:18px 24px}.calc-body{padding:32px 26px 34px}.calc-bar{width:140px}}

/* button aliases: calculator.js emits the original class names */
.btn-yellow{background:var(--gold);color:var(--accent-ink);border-color:var(--gold);box-shadow:0 10px 26px -10px var(--accent-glow)}
.btn-yellow:hover{color:var(--accent-ink);transform:translateY(-2px)}
.btn-primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);box-shadow:0 12px 30px -10px var(--accent-glow)}
.btn-primary:hover{color:var(--accent-ink);transform:translateY(-2px)}
.btn-outline{background:transparent;border-color:var(--gold-line);color:var(--gold)}
.btn-outline:hover{background:var(--gold-soft);color:var(--gold);border-color:var(--gold)}
.btn-ghost{background:transparent;box-shadow:none;color:var(--text-3);border-color:var(--line)}
.btn-ghost:hover{color:var(--danger);border-color:var(--danger)}
.btn-lg{font-size:17.3px;padding:14px 26px;min-height:52px}
.btn-sm{font-size:14.4px;padding:9px 16px;min-height:40px}

/* ---------- the filled card, last word on ink ----------
   These repeat the .fill-card ink rules on purpose. The component sections
   above (.gcard h3, .info-card p, .stat .num and friends) come later in the
   cascade at equal specificity, so without this block a filled card would
   render dark body text on a blue panel. Keep this block at the bottom. */
.gcard.fill-card h3,.info-card.fill-card h3,.stat.fill-card .num,
.gcard.fill-card strong,.info-card.fill-card strong{color:var(--fill-ink)}
.gcard.fill-card p,.info-card.fill-card p,.gcard.fill-card small,
.stat.fill-card .label,.info-card.fill-card .g-link{color:var(--fill-muted)}
.gcard.fill-card .g-link,.info-card.fill-card .g-link{color:var(--fill-muted)}
.stat.fill-card .num{background:none;-webkit-text-fill-color:var(--fill-ink)}
.gcard.fill-card:hover,.info-card.fill-card:hover,.stat.fill-card:hover{
  border-color:transparent;box-shadow:0 0 0 6px var(--plate),var(--fill-glow)}
.info-card.fill-card .g-ico,.gcard.fill-card .g-ico,
.info-card.fill-card .g-ico.wa{background:rgba(255,255,255,.16);border-color:var(--fill-line)}

/* a price table as the section's filled card (offshore's jurisdictions).
   Every hairline and every ink colour has to survive the blue. */
.table-wrap.fill-card .tw-head{color:var(--fill-muted);border-bottom-color:var(--fill-line)}
.table-wrap.fill-card .price-table th{color:var(--fill-muted);border-bottom-color:var(--fill-line)}
.table-wrap.fill-card .price-table td{color:var(--fill-muted);border-bottom-color:rgba(255,255,255,.1)}
.table-wrap.fill-card .price-table td:last-child{color:var(--fill-ink)}
.table-wrap.fill-card .price-table tr.total td{background:rgba(255,255,255,.12);color:var(--fill-ink)}
.table-wrap.fill-card .price-table tr.total td:last-child{color:var(--fill-muted)}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important}
  .reveal{opacity:1;transform:none}
}

/* =========================================================================
   BLOG. The generator (scripts/build-blog.mjs) emits exactly these classes.
   Two surfaces: the INDEX (a card grid in the site's own language, one
   fill-card per view) and an ARTICLE (a centred single column that reads like
   a long-form post, no sidebar, generous measure and type). Phone rules for
   both live in the PHONE EXPERIENCE block below, not here.
   ========================================================================= */

/* ---- category pills. BUTTONS on /blog (they filter the grid in place) and
       LINKS on a category page (they navigate). One class, so the row looks
       identical either way. ---- */
.np-cats{display:flex;flex-wrap:wrap;gap:9px;margin:0 0 28px}
.np-pill{appearance:none;flex:none;display:inline-flex;align-items:center;gap:8px;
  border:1px solid var(--line);background:var(--card-grad);color:var(--text-2);
  font-family:inherit;font-weight:600;font-size:14.4px;border-radius:100px;
  padding:10px 18px;cursor:pointer;white-space:nowrap;min-height:44px;
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.np-pill:hover{border-color:var(--accent);color:var(--accent)}
.np-pill .np-n{font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--text-2)}
.np-pill.on{background:var(--btn-bg);border-color:var(--btn-bg);color:var(--btn-ink);
  box-shadow:0 8px 22px -10px var(--accent-glow)}
.np-pill.on .np-n{color:var(--btn-ink);opacity:.86}

/* ---- the card grid: 3 up on desktop, 2 on a tablet, 1 on a phone ---- */
.np-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:26px;align-items:stretch}
@media (max-width:1024px){.np-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}}

/* ---- the card. Image, then category + read time, then headline, then
       excerpt, then the author footer with the date. It is an <article> and
       not one big <a> on purpose: the category and the headline are separate
       destinations, and a link cannot legally sit inside a link. ---- */
.npcard{display:flex;flex-direction:column;position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--card-grad);
  transition:border-color var(--t) var(--ease),transform var(--t) var(--ease),box-shadow var(--t) var(--ease);
  animation:np-in .42s var(--ease) both}
@keyframes np-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.npcard:hover{border-color:var(--accent);transform:translateY(-3px);box-shadow:var(--shadow-soft)}
.np-img{display:block;aspect-ratio:16/9;overflow:hidden;background:var(--glass);
  border-bottom:1px solid var(--line)}
.np-img img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform var(--t-slow) var(--ease)}
.npcard:hover .np-img img{transform:scale(1.04)}
.np-ico{display:flex;align-items:center;justify-content:center;height:100%;font-size:40px}
.np-body{display:flex;flex-direction:column;flex:1;padding:16px 18px 18px}
.np-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}
.np-cat{min-width:0;font-family:"JetBrains Mono",monospace;font-size:10.4px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--accent);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.np-cat:hover{text-decoration:underline;text-underline-offset:3px}
.np-read,.np-date{display:inline-flex;align-items:center;gap:6px;flex:none;
  font-family:"JetBrains Mono",monospace;font-size:10.4px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--text-3);white-space:nowrap}
.np-i{width:13px;height:13px;flex:none}
.np-h{font-size:19px;font-weight:680;letter-spacing:-.022em;line-height:1.26;margin:0}
.np-h a{color:var(--text-1);transition:color var(--t-fast) var(--ease)}
.npcard:hover .np-h a{color:var(--accent)}
.np-ex{font-size:14.8px;color:var(--text-2);line-height:1.56;margin:9px 0 0;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}

/* the author footer: avatar, name, job title, then the date on the right */
.np-foot{display:flex;align-items:center;gap:10px;margin:auto 0 0;padding-top:15px;
  border-top:1px solid var(--line-soft)}
.np-av{flex:none;width:36px;height:36px;border-radius:50%;object-fit:cover;
  border:1px solid var(--line-strong);background:var(--glass-hi)}
.np-who{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.np-name{font-size:12.8px;font-weight:700;color:var(--text-1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.np-job{font-size:10.6px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.np-foot .np-date{margin-left:auto}

/* ---- our own promo tiles, where Neil Patel sells ad space. No sponsors, so
       no "join 5000 companies" banners: just the next step on this site.
       ui.js places them with CSS order, so filtering never strands one. ---- */
/* the tile stretches to the tallest card in its row, so the copy is centred
   rather than pinned top and bottom with a hole in the middle */
.np-promo{display:flex;flex-direction:column;justify-content:center;position:relative;overflow:hidden;
  border:1px solid var(--line-strong);border-radius:var(--radius);
  background:linear-gradient(158deg,var(--glass-hi),var(--glass));padding:22px 20px 20px}
.np-promo::after{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(var(--dots) 1px,transparent 1px);background-size:20px 20px;opacity:.5;
  mask-image:radial-gradient(ellipse 78% 70% at 82% 0,black,transparent 72%);
  -webkit-mask-image:radial-gradient(ellipse 78% 70% at 82% 0,black,transparent 72%)}
.np-promo>*{position:relative;z-index:1}
.np-p-k{font-family:"JetBrains Mono",monospace;font-size:10.4px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.np-p-h{display:block;font-size:20px;font-weight:700;letter-spacing:-.025em;line-height:1.22;
  margin:10px 0 0;color:var(--text-1)}
.np-promo p{font-size:14.6px;color:var(--text-2);line-height:1.56;margin:9px 0 18px}
.np-p-cta{align-self:flex-start;flex:none}
.np-promo.fill{background:var(--fill);border-color:transparent;color:var(--fill-ink);
  box-shadow:0 0 0 6px var(--plate),var(--fill-glow)}
.np-promo.fill::after{opacity:.3}
.np-promo.fill .np-p-k{color:var(--fill-muted)}
.np-promo.fill .np-p-h{color:var(--fill-ink)}
.np-promo.fill p{color:var(--fill-muted)}
.np-promo.fill .btn.primary{background:#FFFFFF;color:#133875;border-color:transparent;
  box-shadow:0 12px 30px -14px rgba(0,0,0,.5)}
.np-promo.fill .btn.primary:hover{background:#EAF1FF;color:#133875;transform:translateY(-2px)}

/* ---- Load More, in place of the old 1 2 3 4 5 pager ---- */
.np-more{display:flex;flex-direction:column;align-items:center;gap:14px;margin-top:38px}
.np-more .btn{min-width:250px;justify-content:center}
.np-count{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-3);margin:0}
.np-count b{color:var(--accent);font-weight:600}
.np-empty{text-align:center;color:var(--text-2);font-size:16.3px;padding:36px 0}

/* ---- featured card: the newest guide, above the grid ---- */
.bfeat{display:grid;grid-template-columns:1fr;gap:0;margin:0 0 26px;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--radius);background:var(--card-grad);
  transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.bfeat:hover{border-color:var(--accent);box-shadow:var(--shadow-soft)}
.bfeat .bf-body{display:flex;flex-direction:column;padding:20px 18px 22px}
.bfeat .np-h{font-size:24px;font-weight:700;letter-spacing:-.028em;line-height:1.18}
.bfeat .np-ex{font-size:15.4px;-webkit-line-clamp:4}
.bfeat .np-foot{margin-top:16px}
.bfeat .bf-more{align-self:flex-start;margin-top:20px}
.bfeat:hover .np-h a{color:var(--accent)}
@media (min-width:781px){
  /* the image keeps its 16:9 shape and centres itself rather than stretching to
     the row height, so the thumbnail is never cropped on a wide screen */
  .bfeat{grid-template-columns:1.1fr 1fr;align-items:center}
  .bfeat .np-img{align-self:center;border-bottom:0;border-right:1px solid var(--line)}
  .bfeat .bf-body{padding:30px 30px 32px;justify-content:center}
  .bfeat .np-h{font-size:31px}
}
@media (min-width:1025px){
  .bfeat .np-h{font-size:35px}
  .bfeat .bf-body{padding:38px 38px 40px}
}

/* ---- archive ---- */
.archive-wrap{max-width:820px;margin:0 auto}
.archive-group{margin-bottom:34px}
.ar-month{display:flex;align-items:center;gap:12px;font-size:21.8px;font-weight:650;letter-spacing:-.025em;
  padding-bottom:12px;margin-bottom:6px;border-bottom:1px solid var(--line)}
.ar-month .ar-count{font-family:"JetBrains Mono",monospace;font-size:11px;font-weight:600;letter-spacing:.1em;
  color:var(--text-3);border:1px solid var(--line);border-radius:100px;padding:4px 11px}
.archive-list{list-style:none}
.archive-list li{border-bottom:1px solid var(--line-soft)}
.archive-list li:last-child{border-bottom:0}
.archive-list a{display:flex;flex-direction:column;gap:3px;padding:14px 2px;transition:padding var(--t-fast) var(--ease)}
.archive-list a:hover{padding-left:10px}
.archive-list .ar-t{font-size:16.7px;font-weight:600;color:var(--text-1);line-height:1.35;transition:color var(--t-fast) var(--ease)}
.archive-list a:hover .ar-t{color:var(--accent)}
.archive-list .ar-meta{font-family:"JetBrains Mono",monospace;font-size:10.9px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-3)}
.archive-list .ar-meta .bdot{opacity:.6}

/* =========================================================================
   ARTICLE: two columns from 1025px up. The reading column on the left, a
   sticky rail on the right carrying the table of contents and the CTA cards.
   Below 1025px it collapses to one centred column and the TOC goes back to
   being the collapsible strip above the prose.
   ========================================================================= */
.article{position:relative;z-index:1;padding:8px 0 40px}
.article-main{min-width:0;max-width:820px;margin:0 auto}
.art-side{display:none}
@media (min-width:1025px){
  .article-shell{display:grid;grid-template-columns:minmax(0,1fr) 336px;gap:56px}
  .article-main{max-width:none;margin:0}
  .art-side{display:block;min-width:0}
  /* the rail sticks INSIDE its own column, so the column has to keep the
     row's full height. Never add align-items:start to the grid above, that
     shrink-wraps the column and sticky then has nowhere to travel. */
  .art-side-in{position:sticky;top:88px;display:flex;flex-direction:column;gap:16px;
    max-height:calc(100dvh - 108px);overflow-y:auto;overscroll-behavior:contain;
    scrollbar-width:thin;padding-right:2px}
  .toc{display:none}
}
.article-head{margin:18px 0 22px}
.btag.standalone{display:inline-flex;align-items:center;gap:7px;font-family:"JetBrains Mono",monospace;
  font-size:11.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);
  border:1px solid var(--line);border-radius:100px;padding:7px 15px;background:var(--glass);margin:0}
.btag.standalone:hover{border-color:var(--accent)}
.article-head h1{font-size:clamp(31px,4.4vw,49px);font-weight:600;letter-spacing:-.035em;line-height:1.08;margin:16px 0 14px}

/* the byline: avatar, name, job title, then the date and read time.
   When an article has been updated, the shown date is the update date and the
   full history lives in the title attribute and the BlogPosting schema, which
   is what search engines actually read. */
.art-by{display:flex;align-items:center;gap:11px;margin-top:18px;padding-top:16px;
  border-top:1px solid var(--line-soft)}
.art-by .np-av{width:44px;height:44px}
.art-by .np-name{font-size:14.4px}
.art-by .np-job{font-size:11.5px}
.art-by-meta{display:flex;align-items:center;gap:16px;margin-left:auto}
.art-by .d-sm{display:none}

/* ---- the sticky rail ---- */
.side-k{display:block;font-family:"JetBrains Mono",monospace;font-size:10.6px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.side-toc{border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card-grad);
  padding:16px 17px 10px}
/* a 14-heading guide would make the rail taller than the screen and push the
   green Book card out of sight, so the list gets its own scroll and the CTAs
   always stay reachable */
.side-toc-list{list-style:none;counter-reset:stoc;margin-top:10px;position:relative;
  max-height:min(34vh,300px);overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
.side-toc-list li{counter-increment:stoc}
.side-toc-list a{display:flex;gap:10px;padding:8px 0 8px 11px;margin-left:-12px;
  border-left:2px solid transparent;font-size:14.4px;line-height:1.4;color:var(--text-2);
  transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.side-toc-list a::before{content:counter(stoc,decimal-leading-zero);font-family:"JetBrains Mono",monospace;
  font-size:10.6px;color:var(--text-3);flex:none;padding-top:3px}
.side-toc-list a:hover{color:var(--accent)}
.side-toc-list a.on{color:var(--accent);border-left-color:var(--accent);font-weight:600}
.side-toc-list a.on::before{color:var(--accent)}
.side-card{border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card-grad);
  padding:18px 17px}
.side-card strong{display:block;font-size:17.3px;font-weight:700;letter-spacing:-.02em;line-height:1.25;
  color:var(--text-1);margin:9px 0 0}
.side-card strong em{font-style:normal;color:var(--accent)}
.side-card p{font-size:14px;color:var(--text-2);line-height:1.55;margin:8px 0 14px}
.side-card .btn{width:100%;justify-content:center}
.side-card.fill{background:var(--fill);border-color:transparent;
  box-shadow:0 0 0 5px var(--plate),var(--fill-glow)}
.side-card.fill .side-k{color:var(--fill-muted)}
.side-card.fill strong,.side-card.fill strong em{color:var(--fill-ink)}
.side-card.fill p{color:var(--fill-muted)}
.side-card.fill .btn.primary{background:#FFFFFF;color:#133875;border-color:transparent}
.side-card.fill .btn.primary:hover{background:#EAF1FF;color:#133875}

/* the answer-first box, the featured-snippet target */
.article-answer{padding:22px 24px;margin-bottom:26px}
.article-answer .aa-k{font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);margin-bottom:10px}
.article-answer .answer-lead{font-size:19px;line-height:1.66;color:var(--text-1)}
.article-answer .answer-lead+.answer-lead{margin-top:14px}

/* table of contents, collapsible */
.toc{margin:0 0 30px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card-grad);overflow:hidden}
.toc-toggle{appearance:none;width:100%;display:flex;align-items:center;justify-content:space-between;
  background:transparent;border:0;color:var(--text-1);font-family:"JetBrains Mono",monospace;font-size:11.5px;
  font-weight:600;letter-spacing:.16em;text-transform:uppercase;padding:15px 18px;cursor:pointer;min-height:50px}
.toc-toggle .toc-caret{transition:transform var(--t-med) var(--ease);color:var(--accent)}
.toc-toggle[aria-expanded="true"] .toc-caret{transform:rotate(180deg)}
/* the collapse animates ONE wrapper (.toc-body), exactly like the FAQ. Do NOT
   put the 0fr/1fr grid on .toc-list itself: its children are the <li>s, so the
   fr track only sizes the first row and the first item (Step 1) collapses to
   zero while the rest overflow into implicit auto rows. Wrapping fixes it. */
.toc-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--t-med) var(--ease)}
.toc-toggle[aria-expanded="true"]+.toc-body{grid-template-rows:1fr}
.toc-body>*{overflow:hidden;min-height:0}
.toc-list{list-style:none;counter-reset:toc}
.toc-list li{counter-increment:toc;border-top:1px solid var(--line-soft)}
.toc-list a{display:flex;gap:11px;padding:12px 18px;font-size:15.5px;color:var(--text-2);line-height:1.4;
  transition:color var(--t-fast) var(--ease),background var(--t-fast) var(--ease)}
.toc-list a::before{content:counter(toc,decimal-leading-zero);font-family:"JetBrains Mono",monospace;
  font-size:11.5px;color:var(--accent);flex:none;padding-top:2px}
.toc-list a:hover{color:var(--accent);background:var(--glass-hi)}
/* on a wide screen the TOC can stay open by default, it is not in the way */
@media (min-width:721px){
  .toc-body{grid-template-rows:1fr}
  .toc-toggle{cursor:default;pointer-events:none}
  .toc-toggle .toc-caret{display:none}
}

/* the prose body: the whole point is that it reads better than Shuraa */
.prose{font-size:19px;line-height:1.78;color:var(--text-1)}
.prose>*+*{margin-top:22px}
.prose p{color:var(--text-1);font-weight:400}
.prose h2{font-size:clamp(25px,3vw,32px);font-weight:620;letter-spacing:-.03em;line-height:1.18;
  margin-top:44px;scroll-margin-top:84px}
.prose h2:first-child{margin-top:0}
.prose h3{font-size:21px;font-weight:650;letter-spacing:-.02em;line-height:1.3;margin-top:30px}
.prose a{color:var(--accent);font-weight:600;text-decoration:underline;text-underline-offset:2px;
  text-decoration-color:var(--line-strong);transition:text-decoration-color var(--t-fast) var(--ease)}
.prose a:hover{text-decoration-color:var(--accent)}
.prose strong{color:var(--text-1);font-weight:700}
.prose-ul,.prose-ol{padding-left:0;list-style:none;display:flex;flex-direction:column;gap:12px}
.prose-ul li,.prose-ol li{position:relative;padding-left:32px;color:var(--text-1);line-height:1.65}
.prose-ul li::before{content:"";position:absolute;left:8px;top:12px;width:7px;height:7px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
.prose-ol{counter-reset:pro}
.prose-ol li{counter-increment:pro}
.prose-ol li::before{content:counter(pro);position:absolute;left:0;top:1px;width:24px;height:24px;border-radius:50%;
  background:var(--accent-soft);border:1px solid var(--line);color:var(--accent);font-family:"JetBrains Mono",monospace;
  font-size:12px;font-weight:600;display:flex;align-items:center;justify-content:center}
.prose-table{margin-top:26px;margin-bottom:26px}
.prose-quote{border-left:3px solid var(--accent);padding:6px 0 6px 22px;margin:28px 0;
  font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;font-style:italic;font-weight:300;font-size:22px;line-height:1.5;
  color:var(--text-1);letter-spacing:-.02em}

/* inline note / tip */
.prose-note{display:flex;gap:14px;align-items:flex-start;margin:28px 0;padding:18px 20px;border-radius:var(--radius-sm);
  border:1px solid var(--line);background:linear-gradient(150deg,var(--accent-soft),transparent 64%),var(--card-grad)}
.prose-note.tip{border-color:var(--gold-line);background:linear-gradient(150deg,var(--gold-soft),transparent 64%),var(--card-grad)}
.prose-note .pn-ico{flex:none;width:38px;height:38px;border-radius:11px;display:flex;align-items:center;justify-content:center;
  font-size:18px;background:var(--accent-soft);border:1px solid var(--line)}
.prose-note.tip .pn-ico{background:var(--gold-soft);border-color:var(--gold-line)}
.prose-note .pn-t{display:block;font-family:"JetBrains Mono",monospace;font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);margin-bottom:6px}
.prose-note.tip .pn-t{color:var(--gold)}
.prose-note p{font-size:16px;color:var(--text-2);line-height:1.62;margin:0}

/* key takeaways box, sits high in the article */
.takeaways{margin:26px 0;padding:20px 22px;border-radius:var(--radius-sm);border:1px solid var(--line-strong);
  background:linear-gradient(158deg,var(--glass-hi),var(--glass))}
.takeaways .tk-t{display:block;font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--accent);margin-bottom:14px}
.takeaways ul{list-style:none;display:flex;flex-direction:column;gap:11px}
.takeaways li{position:relative;padding-left:30px;font-size:16.3px;line-height:1.55;color:var(--text-1)}
.takeaways li::before{content:"";position:absolute;left:6px;top:9px;width:8px;height:8px;border-radius:2px;
  transform:rotate(45deg);background:var(--accent)}

/* the inline calculator CTA (calculator-only, per the build decision) */
.prose-cta{display:flex;align-items:center;gap:18px;flex-wrap:wrap;justify-content:space-between;
  margin:32px 0;padding:22px 24px;border-radius:var(--radius);background:var(--fill);color:var(--fill-ink);
  border:1px solid transparent;box-shadow:0 0 0 6px var(--plate),var(--fill-glow);position:relative;overflow:hidden}
.prose-cta::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 70% 60% at 10% -10%,rgba(215,251,227,.3),transparent 62%),
  radial-gradient(circle,rgba(255,255,255,.09) 1px,transparent 1px);background-size:auto,22px 22px;opacity:.9}
.prose-cta>*{position:relative;z-index:1}
.prose-cta .pc-k{display:block;font-family:"JetBrains Mono",monospace;font-size:10.9px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--fill-muted);margin-bottom:7px}
.prose-cta strong{display:block;font-size:20px;font-weight:650;color:var(--fill-ink);letter-spacing:-.02em;line-height:1.25}
.prose-cta p{font-size:15px;color:var(--fill-muted);margin:6px 0 0;max-width:440px;line-height:1.55}
.prose-cta .btn{flex:none;background:#FFFFFF;color:#133875;border-color:transparent;box-shadow:0 12px 30px -14px rgba(0,0,0,.5)}
.prose-cta .btn:hover{background:#EAF1FF;color:#133875;transform:translateY(-2px)}

/* the article FAQ reuses the .faq accordion; just spacing around it */
.article-faq{margin-top:46px}
.article-faq>h2{font-size:clamp(25px,3vw,32px);font-weight:620;letter-spacing:-.03em;margin-bottom:18px;text-align:center}
.article-faq .faq{margin-top:0}
.article-cta{margin-top:40px}
.article-related{position:relative;z-index:1;padding-top:8px}

/* ════════════════════════ PHONE EXPERIENCE ════════════════════════
   Effectively all of this site's traffic is on phones, so the phone layout is
   its own thing, not the desktop layout squeezed. Everything phone-specific
   lives in this ONE block so it is easy to find and tune later.
   Carried over from the command center: bottom sheets instead of centred
   boxes, icon-only in tight bars, fields paired two to a row, headers stacked
   instead of squeezed, pill rows that scroll sideways, tighter frames.
   ════════════════════════════════════════════════════════════════ */
@media (max-width:720px){
  /* tighter frames: page padding 24/16, card padding 20/17, radius 18 */
  :root{--radius:18px}
  section{padding:44px 0}
  /* DP, 2026-07-25: one gutter for the WHOLE site on a phone. The new sections
     used 16px and the ported legacy sections used 18px, so nothing lined up as
     you scrolled and cards read as if they were touching the screen edge.
     20px each side, matched in scanner.css, is the single source of truth. */
  .wrap{width:calc(100% - 40px)}

  /* phones scroll a lot: reveals FADE only, no upward slide (the 16px shift
     read as jumpy boxes while scrolling, DP 2026-07-23) */
  .reveal{transform:none;transition:opacity .45s var(--ease)}
  .reveal.in{transform:none}
  .tnode{transform:none}
  .tnode.lit{transform:none}

  /* no green glow pinned to the viewport edges on phones: the fixed radial
     washes read as an ugly fade at the top and bottom while scrolling */
  /* flat on phones too. No vertical wash. */
  .ambient{background:var(--bg-0)}
  [data-theme="light"] .ambient{background:var(--bg-0)}

  /* the bar carries the brand, the theme toggle and the menu. No page can
     afford a label-heavy header at 375px: the labels go, the icons stay. */
  .topbar{background:var(--bg-1);backdrop-filter:none;-webkit-backdrop-filter:none}
  [data-theme="light"] .topbar{background:var(--bg-1)}
  .topbar-inner{gap:10px;padding:9px 0}
  /* the horizontal lockup stays height-driven on phones too, never squashed
     back to a square */
  .brand img{height:31px;width:auto}
  /* the mark swaps with the theme: white art on dark, navy art on light,
   exactly the guidelines' logo usage rules */
.logo-on-dark{display:block}
.logo-on-light{display:none}
[data-theme="light"] .logo-on-dark{display:none}
[data-theme="light"] .logo-on-light{display:block}
.brand .b-name{font-size:15.5px}
  .brand .b-sub{font-size:9.4px;letter-spacing:.16em}
  .topbar-cta{gap:7px;margin-left:auto}

  /* the menu rises from the bottom edge, the way a phone menu should.
     The bar drops its backdrop-filter above precisely so this can be fixed to
     the viewport: a filtered ancestor becomes the containing block for fixed
     children and the sheet would open inside the header instead. */
  .navlinks{position:fixed;top:auto;left:0;right:0;bottom:0;
    border-radius:22px 22px 0 0;border:1px solid var(--line);border-bottom:0;
    padding:12px 16px calc(16px + env(safe-area-inset-bottom));
    max-height:82dvh;overflow-y:auto;overscroll-behavior:contain;
    box-shadow:0 -30px 70px -20px rgba(0,0,0,.7);
    transform:translateY(102%);opacity:1;z-index:90}
  /* the grab handle, so it reads as a sheet and not a stuck panel */
  .navlinks::before{content:"";flex:none;width:38px;height:4px;border-radius:99px;
    background:var(--line-strong);align-self:center;margin-bottom:10px}
  .navlinks.open{transform:translateY(0)}
  /* the dim behind the sheet. It cannot live on .navlinks::before: the sheet
     scrolls, and overflow:auto clips its own pseudo-elements. */
  .topbar:has(.navlinks.open)::after{content:"";position:fixed;inset:0;z-index:1;
    background:rgba(2,5,12,.62);animation:scrim-in var(--t-med) var(--ease) both}
  [data-theme="light"] .topbar:has(.navlinks.open)::after{background:rgba(14,26,51,.45)}
  @keyframes scrim-in{from{opacity:0}to{opacity:1}}
  /* the brand and the close button stay above the dim so the sheet can be shut */
  .brand,.topbar-cta{position:relative;z-index:3}
  .navlinks a{padding:13px 14px;font-size:17.3px;min-height:50px;display:flex;align-items:center;border-radius:12px}
  .navlinks a.on{background:var(--accent-soft);color:var(--accent)}

  /* hero */
  .hero{padding:28px 0 36px}
  .hero h1{margin:16px 0 12px}
  .hero .lead{font-size:17.3px}
  .hero-ctas{gap:10px;margin-top:20px}
  .hero-ctas .btn,.result-ctas .btn{flex:1 1 100%}
  /* the eyebrow drops its pill frame on phones: one quiet mono line, no box */
  .hero .eyebrow{border:0;background:transparent;box-shadow:none;padding:0;font-size:10.4px;letter-spacing:.12em;gap:7px}
  /* trust proof reads as one plain line with dot separators, so it stops
     competing with the two real buttons above it. The .chip-x tails are
     hidden here so all three fit a 375px line. */
  .hero-trust{gap:0;margin-top:16px;flex-wrap:nowrap;align-items:center;justify-content:flex-start;white-space:nowrap}
  .hero-trust > span{border:0;background:transparent;padding:0;font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;font-size:11px;letter-spacing:0}
  .hero-trust i{display:none}
  .hero-trust > span + span::before{content:"\00B7";margin:0 7px;color:var(--text-3)}
  .hero-trust .chip-x{display:none}
  /* the scroll cue between the hero copy and the snapshot card */
  .scroll-cue{display:flex;justify-content:center;margin:20px 0 2px;color:var(--accent);animation:cue-bob 2s var(--ease) infinite}
  .scroll-cue svg{width:20px;height:20px}

  /* cards: less frame, more content */
  .gcard,.quote,.info-card,.answer-card,.form-card{padding:20px 17px}
  .est-card{padding:20px 17px}
  .band{padding:30px 20px}
  .stat{padding:20px 12px}
  .gcard::before,.quote::before,.info-card::before,.stat::before,.est-card::before,
  .band::before,.step::before,.tnode .t-card::before{left:16px;right:16px}
  .gcard h3{font-size:20px}
  .gcard .g-link{padding-top:16px;min-height:44px;align-items:center}
  .sec-head{margin-bottom:22px}

  /* a squeezed header renders its subtitle one word per line. Stack it. */
  .calc-head{flex-wrap:wrap;align-items:center;gap:10px 12px}
  .calc-head .title{flex:1 0 100%}
  .calc-progress{flex:1;min-width:0}
  .calc-bar{flex:1;width:auto}
  .calc-xp{flex:none}
  .gpt-head{gap:8px}
  .gpt-head .gh-new{margin-left:auto}

  /* pair fields two to a row instead of stacking every field on its own line */
  .form-grid{grid-template-columns:1fr 1fr;gap:10px}
  .field label{font-size:10.4px;letter-spacing:.12em}

  /* the estimate total: stack it so the AED figure never wraps mid-number */
  .est-total{flex-direction:column;align-items:flex-start;gap:2px}
  .est-total strong{font-size:28px}
  .est-row{font-size:14.8px}

  /* quotes and FAQ stay readable, not shrunk */
  .quote p{font-size:18.4px}
  .faq-q{font-size:16.7px;padding:16px 16px}
  .faq-a p{padding:0 16px 18px;font-size:15.5px}

  /* the price tables: tighter cells so most of them fit without the inner
     sideways scroll. The scroll stays as the fallback for the wide ones. */
  .price-table th{padding:12px 12px;font-size:10.9px}
  .price-table td{padding:12px 12px;font-size:14.4px}
  .price-table td:last-child{font-size:13.2px}
  .table-wrap .tw-head{padding:14px 16px;font-size:11.5px}

  /* the footer link columns */
  .foot-brand p{font-size:15px}

  /* ── DBC GPT on a phone ──────────────────────────────────────────
     You land IN the chat. The header above it is cut to the headline, the
     breadcrumb goes, and the topic list moves into a bottom sheet, so the
     composer is on screen the moment the page opens and never moves after. */
  .gpt-section{--gpt-chrome:196px}
  .gpt-page-hero{padding:14px 0 12px}
  .gpt-page-hero .eyebrow,.gpt-page-hero .lead{display:none}
  .gpt-page-hero h1{font-size:25px;margin:0;line-height:1.15}
  .gpt-section .crumbs,.gpt-crumbs{display:none}
  .gpt-wrap{gap:0;min-height:400px}

  .gpt-head{padding:11px 14px;gap:8px}
  .gpt-head .gh-s{display:none}
  .gpt-head .gh-topics{display:inline-flex;margin-left:auto}
  .gpt-head .gh-new{margin-left:0}
  .gpt-head .btn.sm{font-size:13.2px;padding:8px 13px;min-height:38px}
  .gpt-log{padding:16px 14px 6px;gap:15px}
  .gpt-msg .gm-body{font-size:16px}
  /* a hairline over the chips row: chat text clips against the composer area
     while scrolling, and without a separator the cut read as broken layout */
  .gpt-starters{padding:9px 14px 0;border-top:1px solid var(--line)}
  .gpt-form{padding:10px 14px 6px}
  .gpt-note{font-size:11.5px;padding:2px 14px calc(10px + env(safe-area-inset-bottom))}

  /* the topic list rises from the bottom, like every other sheet on the site.
     transform:none matters: .reveal leaves an identity transform behind, and a
     transformed element cannot host a fixed-position sheet correctly. */
  .gpt-side{position:fixed;left:0;right:0;bottom:0;top:auto;z-index:90;
    opacity:1;transform:translateY(102%);
    border-radius:22px 22px 0 0;border:1px solid var(--line);border-bottom:0;
    padding:10px 14px calc(14px + env(safe-area-inset-bottom));
    max-height:78dvh;box-shadow:0 -30px 70px -20px rgba(0,0,0,.7);
    transition:transform var(--t-med) var(--ease)}
  .gpt-side.open{transform:translateY(0)}
  .gs-sheet-head{display:flex;align-items:center;gap:10px;flex:none;
    padding:2px 2px 10px;margin-bottom:6px;border-bottom:1px solid var(--line)}
  .gs-sheet-head span{font-family:"JetBrains Mono",monospace;font-size:11.5px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--text-3)}
  .gs-close{margin-left:auto;appearance:none;width:38px;height:38px;border-radius:50%;
    border:1px solid var(--line);background:var(--glass-hi);color:var(--text-2);
    font-size:15px;cursor:pointer;display:flex;align-items:center;justify-content:center}
  .gpt-topic{font-size:16.7px;min-height:48px}
  /* the dim behind the sheet, on the section so the sheet's own scroll cannot clip it */
  .gpt-section:has(.gpt-side.open)::after{content:"";position:fixed;inset:0;z-index:89;
    background:rgba(2,5,12,.62);animation:scrim-in var(--t-med) var(--ease) both}
  [data-theme="light"] .gpt-section:has(.gpt-side.open)::after{background:rgba(14,26,51,.45)}

  /* ── BLOG on a phone ─────────────────────────────────────────────
     The filter pills scroll sideways instead of wrapping into a tall block.
     ONE card per row (DP, 2026-07-25): the Neil Patel card carries an author
     footer with an avatar, a name and a job title, and that simply cannot be
     read at 167px, which is what a 2-up card is on a 375px screen. The
     article column loses its side gutters so the measure stays generous, and
     the prose type steps down so it is comfortable, not shrunk. */
  .np-cats{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;
    gap:8px;margin:0 0 20px;padding-bottom:2px}
  .np-cats::-webkit-scrollbar{display:none}
  .np-pill{font-size:13.6px;padding:9px 15px}

  .np-grid{grid-template-columns:1fr;gap:16px}
  .np-body{padding:14px 16px 16px}
  .np-h{font-size:18.4px}
  .np-ex{font-size:14.4px}
  .np-promo{padding:20px 17px 18px}
  .np-p-h{font-size:19px}
  .np-more{margin-top:30px}
  .np-more .btn{width:100%;min-width:0}

  /* featured card */
  .bfeat .np-h{font-size:21px}
  .bfeat .bf-body{padding:17px 15px 19px}
  .bfeat .np-ex{font-size:14.6px}

  /* article */
  .article{padding:4px 0 32px}
  .article-head{margin:14px 0 18px}
  /* the byline holds ONE line on a phone: avatar, name, date, read time.
     The job title is the thing that goes, it is already in the schema. */
  .art-by{gap:9px;margin-top:15px;padding-top:13px;flex-wrap:nowrap}
  .art-by .np-av{width:38px;height:38px}
  .art-by .np-name{font-size:13.2px}
  .art-by .np-job{display:none}
  .art-by-meta{gap:10px;min-width:0;flex:none}
  .art-by-meta .np-date,.art-by-meta .np-read{font-size:9.4px;letter-spacing:.03em;gap:5px}
  .art-by-meta .np-i{width:11px;height:11px}
  .art-by .d-lg{display:none}
  .art-by .d-sm{display:inline}
  .article-answer{padding:18px 17px}

  /* DP, 2026-07-25: on a phone the "On this page" bar is shut by default and
     people scrolled straight past it. While it is SHUT it breathes a green
     ring, gives an occasional wobble and bobs its caret, so it reads as a
     thing you can tap. The moment it opens, aria-expanded flips to true, the
     :has() below stops matching and the bar goes completely still. */
  .toc:has(.toc-toggle[aria-expanded="false"]){
    border-color:var(--accent);
    animation:toc-pulse 2.3s var(--ease) infinite, toc-wobble 6s var(--ease) infinite}
  @keyframes toc-pulse{
    0%,100%{box-shadow:0 0 0 0 var(--accent-glow)}
    55%{box-shadow:0 0 0 9px transparent}
  }
  @keyframes toc-wobble{
    0%,86%,100%{transform:none}
    89%{transform:rotate(-.55deg)}
    92%{transform:rotate(.55deg)}
    95%{transform:rotate(-.28deg)}
  }
  .toc-toggle[aria-expanded="false"]{color:var(--accent)}
  .toc-toggle[aria-expanded="false"] .toc-caret{animation:toc-bob 1.5s var(--ease) infinite}
  @keyframes toc-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(3px)}}
  /* nobody should get a wobbling box if they asked the phone to calm down */
  @media (prefers-reduced-motion:reduce){
    .toc:has(.toc-toggle[aria-expanded="false"]){animation:none;box-shadow:0 0 0 3px var(--accent-soft)}
    .toc-toggle[aria-expanded="false"] .toc-caret{animation:none}
  }
  .article-answer .answer-lead{font-size:17.3px}
  .prose{font-size:17.3px;line-height:1.72}
  .prose>*+*{margin-top:19px}
  .prose h2{margin-top:36px}
  .prose-cta{padding:20px 18px;gap:14px}
  .prose-cta .btn{flex:1 1 100%}
  .takeaways{padding:18px 17px}
  .prose-note{padding:16px 16px}
  .archive-list .ar-t{font-size:15.8px}

  /* Article tables stay TABLES on a phone (DP, 2026-07-23): the box keeps its
     card frame and the grid scrolls sideways inside .table-scroll when it is
     wider than the screen. Compact type keeps the rows short instead of the
     old stacked-card layout that ate vertical space. */
  .prose-table .tw-head{padding:13px 16px;font-size:10.4px;letter-spacing:.12em}
  .prose-table .table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .prose-table table.price-table{min-width:480px}
  .prose-table th{padding:10px 12px;font-size:9.8px;letter-spacing:.1em}
  .prose-table td{padding:10px 12px;font-size:13.2px;white-space:normal}
  .prose-table td:last-child{font-size:12.1px}
}
@media (max-width:380px){
  /* the mark swaps with the theme: white art on dark, navy art on light,
   exactly the guidelines' logo usage rules */
.logo-on-dark{display:block}
.logo-on-light{display:none}
[data-theme="light"] .logo-on-dark{display:none}
[data-theme="light"] .logo-on-light{display:block}
.brand .b-name{font-size:14.4px}
  .brand .b-sub{font-size:8.8px}
  .stepper .count{font-size:44px;min-width:74px}
}


/* ---------- handwritten aside (Caveat), the DP wink ----------
   On dark it runs pale yellow. On white, yellow lettering is unreadable, so it
   drops to deep bronze: same hue family, actual contrast. */
.hand{font-family:"Caveat",cursive;font-size:21px;font-weight:500;color:var(--accent-2);letter-spacing:0;transform:rotate(-1.6deg);display:inline-block;line-height:1.3}
[data-theme="light"] .hand{color:#2E6BD3}


/* ---------- author byline is now a link to the Dr. Ronak Patel profile ----------
   The name element was a <span>; it is an <a> from v15 so every article credits
   one canonical Person entity. It has to stay display:block or the ellipsis
   truncation that keeps the byline on one phone line stops working. */
a.np-name{display:block;text-decoration:none;color:var(--text-1);
  transition:color var(--t-fast) var(--ease)}
a.np-name:hover,a.np-name:focus-visible{color:var(--accent)}

/* ---------- explanatory in-article image ----------
   Used only where a picture teaches something a paragraph cannot: an exercise
   position, an anatomical region, a recovery setup. Never decoration, so it
   gets a real caption and reads as content, not as a banner. */
.prose-fig{margin:26px 0;border:1px solid var(--line);border-radius:var(--r-lg,18px);
  overflow:hidden;background:var(--card-grad)}
.prose-fig img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
.prose-fig figcaption{padding:12px 16px;font-size:13.6px;line-height:1.55;
  color:var(--text-3);border-top:1px solid var(--line-soft)}
@media (max-width:720px){
  .prose-fig{margin:20px 0}
  .prose-fig figcaption{padding:10px 13px;font-size:12.8px}
}


/* ════════════════════════ TYPE LIFT ════════════════════════
   Standing order (DP, 2026-07-26): type starts around 125%, small caps mono
   labels never go below 13px, and text is never crowded. The card language
   above is proven and stays untouched, so the lift lives HERE as an additive
   override block. Delete this block and the site returns to the old scale.

   Floors applied: body 20px, article prose 20.5px, card copy 16.5px, every
   mono label 13px, prose measure capped near 70ch.
   ═══════════════════════════════════════════════════════════ */
body{font-size:20px}

/* the reading surface */
.prose{font-size:20.5px;line-height:1.75}
.prose>*+*{margin-top:24px}
.prose p{max-width:70ch}
.prose h2{font-size:clamp(28px,3.4vw,38px);margin-top:50px}
.prose h3{font-size:23px;margin-top:34px}
.prose-ul li,.prose-ol li{line-height:1.68}
.prose-quote{font-size:24px}
.prose-note p{font-size:17.5px}
.takeaways li{font-size:18px;line-height:1.6}
.article-answer .answer-lead{font-size:21.5px;line-height:1.64}
.article-head h1{font-size:clamp(34px,5vw,58px)}
.article-head .art-sub,.article-head p{font-size:19px}
.toc-list a{font-size:17px}
.prose-cta strong{font-size:21.5px}
.prose-cta p{font-size:16.5px}
.article-faq>h2{font-size:clamp(28px,3.4vw,38px)}

/* the card grid on the blog index */
.np-h{font-size:20.5px}
.np-ex{font-size:16.5px;line-height:1.55}
.np-name{font-size:14px}
.np-job{font-size:12.5px}
.bfeat .np-h{font-size:26px}
.bfeat .np-ex{font-size:17px}
.np-p-h{font-size:22px}
.np-promo p{font-size:16.5px}
.np-empty{font-size:18px}

/* MONO LABEL FLOOR: 13px, never smaller. Small caps mono under 13px was the
   exact thing DP called out, so every label on a reading surface is listed. */
.np-cat,.np-read,.np-date,.np-count,.np-p-k,
.crumbs,.eyebrow,.sec-kicker,.brand .b-sub,
.article-answer .aa-k,.toc-toggle,.toc-list a::before,
.prose-note .pn-t,.takeaways .tk-t,.prose-cta .pc-k,
.side-card .side-k,.proof-note,.kb-count,.gpt-head .gh-s,
.gpt-side h3,.site-foot h4,.foot-bottom,.stat .label{font-size:13px}
.prose-ol li::before{font-size:13px}

/* do not crowd the text: more air inside every card at this scale */
.np-body{padding:18px 20px 20px}
.takeaways{padding:24px 26px}
.prose-note{padding:20px 22px}

@media (max-width:720px){
  body{font-size:18.5px}
  .prose{font-size:19px}
  .prose h2{font-size:clamp(25px,6.4vw,30px)}
  .prose h3{font-size:21px}
  .article-answer .answer-lead{font-size:19.5px}
  .np-h{font-size:19px}
  .np-ex{font-size:15.5px}
  .bfeat .np-h{font-size:22px}
  /* the mono floor relaxes by half a point on a phone, and no further */
  .np-cat,.np-read,.np-date,.crumbs,.eyebrow,.sec-kicker{font-size:12.5px}
}


/* ════════════════════════ WORDMARK ════════════════════════
   DP, 2026-07-26: the logo runs in the VaynerMedia lockup. One word, no gap,
   all caps, heavy first half against a light second half. Monochrome on
   purpose: it takes --text-1, so it is near-white on the dark theme and
   near-black on the light one, and the yellow stays for accents only.
   ═════════════════════════════════════════════════════════ */
.brand .wm{
  display:inline-block;
  font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
  font-size:23px;
  font-weight:400;
  letter-spacing:-.012em;
  text-transform:uppercase;
  color:var(--text-1);
  line-height:1;
  white-space:nowrap;
  transition:opacity var(--t-fast) var(--ease);
}
.brand .wm b{font-weight:800;letter-spacing:-.026em}
.brand:hover .wm{opacity:.72}
.site-foot .brand .wm{font-size:21px}
@media (max-width:720px){
  .brand .wm{font-size:20px}
  .site-foot .brand .wm{font-size:19px}
}


/* ════════════════════ READABILITY PASS (DP, 2026-07-26) ════════════════════
   Five asks, in one additive block so it stays reversible:
     1. Titles heavier.
     2. Short-answer box matches body size (it was a point bigger for no reason).
     3. More left and right padding everywhere.
     4. Tables STACK on a phone. No sideways scrolling, ever.
     5. (gradients were removed higher up, in the .ambient block)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ---- 1. titles heavier ---- */
.article-head h1{font-weight:800;letter-spacing:-.038em}
.page-hero h1{font-weight:800;letter-spacing:-.038em}
.hero h1{font-weight:800;letter-spacing:-.038em}
.sec-head h2{font-weight:780;letter-spacing:-.034em}
.prose h2{font-weight:780;letter-spacing:-.032em}
.prose h3{font-weight:750}
.article-faq>h2{font-weight:780}
.np-h{font-weight:780;letter-spacing:-.026em}
.bfeat .np-h{font-weight:800;letter-spacing:-.03em}
.np-p-h{font-weight:800}
.gcard h3,.step h3,.fitcard h3,.side-card strong{font-weight:780}
.band h2{font-weight:800;letter-spacing:-.036em}
/* the italic hook word keeps its light weight on purpose, that contrast is the
   whole point of the lockup. Do not bold it with the rest. */
h1 em,h2 em,h3 em,.it{font-weight:300}

/* ---- 2. the short answer reads at body size ---- */
.article-answer .answer-lead{font-size:20.5px;line-height:1.7}
@media (max-width:720px){.article-answer .answer-lead{font-size:19px}}

/* ---- 3. more breathing room left and right ---- */
.wrap{width:min(1180px,calc(100% - 56px))}
@media (min-width:721px){.wrap{width:min(1180px,calc(100% - 88px))}}
@media (max-width:720px){.wrap{width:calc(100% - 48px)}}
/* cards get more inside padding at the same time, otherwise a wider gutter just
   moves the crowding one layer in */
.np-body{padding:20px 22px 22px}
.takeaways{padding:26px 28px}
.prose-note{padding:22px 24px}
.gcard,.step,.side-card{padding:24px 26px}
@media (max-width:720px){
  .np-body{padding:18px 19px 20px}
  .takeaways{padding:22px 22px}
  .prose-note{padding:19px 20px}
  .gcard,.step,.side-card{padding:21px 21px}
}

/* ---- 4. TABLES STACK ON A PHONE ----
   The old behaviour forced a 480px min-width and let the box scroll sideways,
   so on a 375px screen the last column was off-screen and people had to drag.
   Below 720px every row becomes its own block: the first cell is the row title,
   and each remaining cell prints its column header from data-label beside the
   value. Nothing is hidden and nothing scrolls. The generator already emits
   data-label on every td, so this needs no content changes. */
@media (max-width:720px){
  .prose-table .table-scroll{overflow-x:visible}
  .prose-table table.price-table{min-width:0;width:100%;display:block}
  .prose-table .price-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .prose-table .price-table tbody,
  .prose-table .price-table tr{display:block;width:100%}
  .prose-table .price-table tr{
    padding:14px 16px;
    border-bottom:1px solid var(--line);
  }
  .prose-table .price-table tr:last-child{border-bottom:0}
  .prose-table .price-table td{
    display:flex;
    align-items:baseline;
    justify-content:space-between;
    gap:14px;
    width:100%;
    padding:5px 0;
    border:0;
    font-size:15.5px;
    text-align:right;
    white-space:normal;
  }
  /* first cell in a row is the row's own title: full width, no label, bolder */
  .prose-table .price-table td:first-child{
    display:block;
    text-align:left;
    font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
    font-size:16.5px;
    font-weight:750;
    color:var(--text-1);
    padding-bottom:9px;
    margin-bottom:5px;
    border-bottom:1px solid var(--line-soft);
  }
  .prose-table .price-table td:first-child::before{content:none}
  /* every other cell prints its column header on the left */
  .prose-table .price-table td::before{
    content:attr(data-label);
    flex:0 0 auto;
    text-align:left;
    font-family:"JetBrains Mono",monospace;
    font-size:13px;
    font-weight:600;
    letter-spacing:.1em;
    text-transform:uppercase;
    color:var(--text-3);
  }
  /* a header-less column would leave a dangling colon, so hide the label slot */
  .prose-table .price-table td[data-label=""]::before{content:none}
  .prose-table .price-table td:last-child{
    font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
    font-size:15.5px;
    font-weight:600;
    color:var(--text-1);
  }
  .prose-table .tw-head{font-size:13px;letter-spacing:.14em;padding:14px 16px}
}

/* ==========================================================================
   FEATURED CARD MOBILE OVERFLOW FIX (2026-07-27)
   Additive. Deletes cleanly, does not restructure the card components above.

   THE BUG. `.bfeat` is `grid-template-columns:1fr`, and `1fr` is shorthand for
   `minmax(auto, 1fr)`. That `auto` minimum is the track's min-content width, so
   a child that cannot shrink (here the `.np-top` row: category label plus read
   time, laid out with flex and no wrapping) pushes the track WIDER than the
   card itself. On a 375px screen the track resolved to ~374px inside a 327px
   card. `.bfeat` has `overflow:hidden`, so instead of a horizontal scrollbar
   the title was silently clipped mid-word and the page-level
   `scrollWidth === clientWidth` check still passed. That is why this survived
   the earlier mobile pass: nothing overflowed the PAGE, the card clipped itself.

   THE FIX. `minmax(0,1fr)` lets the track shrink to the container and
   `min-width:0` stops the text children re-inflating it. The meta row is left
   alone: it already ellipsises correctly by itself. Verified at a true 375px in both themes:
   track 325px inside a 327px card, zero elements past the right edge.
   ========================================================================== */
.bfeat{grid-template-columns:minmax(0,1fr)}
.bfeat .np-h,
.bfeat .np-ex{min-width:0;overflow-wrap:anywhere}

/* NOTE (2026-07-27): an earlier version of this fix also set
   `.bfeat .np-top{flex-wrap:wrap}`. That was wrong and DP spotted it on his
   phone: it pushed "7 MIN READ" onto its own orphan line under the category,
   which desktop never did. It was never needed. The real overflow cause was the
   grid track above, and the base `.np-cat` already carries min-width:0 with
   ellipsis while `.np-read` is flex:none, so the row shrinks correctly on its
   own. Category and read time share one line at every width, as designed. */

@media (min-width:860px){
  /* the two-column desktop layout is unchanged, just made shrink-safe */
  .bfeat{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr)}
}

/* ==========================================================================
   AUTHOR BYLINE: REAL PHOTO + ROLE UNDER THE NAME (DP, 2026-07-27)
   Additive. Deletes cleanly.

   DP asked for his actual photo as the author image and for his role to sit
   under his name with proper padding. The role string itself lives in
   scripts/build-blog.mjs as AUTHOR_ROLE, not here.

   Two things were in the way. The role was set to a different string in the
   generator (fixed there, not here), and `.art-by .np-job{display:none}` hid it
   entirely below 720px because the original rule was that the article byline
   must hold ONE ROW on a phone. That rule still holds: `.np-who` is a flex
   COLUMN, so showing the role makes that one column two lines tall, it does not
   add a second row to the byline. The avatar simply grows to match.
   ========================================================================== */
.np-who{gap:2px}
.np-av{background:#FCD200}   /* matches the photo's own backdrop exactly, so the circle never flashes a different colour while it loads */

/* THE AVATAR IS PRE-COMPOSED, DO NOT RE-CROP IT (DP, 2026-07-27).
   DP asked that the circle show his smiling face AND the pointing hand, with
   nothing chopped. A circle only reveals the disc inscribed in the square, so
   the source was padded rather than cropped: the must-show region (full head
   from the hair down, plus the whole hand) was centred on a square canvas big
   enough that the region's DIAGONAL fits inside the circle, and the remainder
   filled with the photo's own backdrop #FCD200. The file is therefore already
   square and already safe. Keep `object-fit:cover` on a square box, which
   crops nothing, and never add a tighter crop or a zoom here. */

@media (max-width:720px){
  /* the role comes back on phones, with the padding DP asked for */
  .art-by .np-job{display:block;font-size:10.8px;line-height:1.3;margin-top:1px}
  .art-by{align-items:center}
  .art-by .np-av{width:42px;height:42px}
  /* the meta column must not squeeze the name now that the column is taller */
  .art-by-meta{flex-wrap:wrap;justify-content:flex-end;row-gap:2px}
}

@media (max-width:400px){
  /* tightest phones: keep the role, drop the read time instead. The role is
     brand, the read time is a nicety and it is still in the schema. */
  .art-by-meta .np-read{display:none}
}


/* ==========================================================================
   ASK DP AVATAR (DP, 2026-07-27)
   The assistant answers in the first person as him, so the bubble carries his
   photo instead of the letters "AI". The image is pre-cropped square and
   face-centred, so `cover` on a square box crops nothing further. The gradient
   stays as the loading colour underneath and as the visitor's own chip.
   ========================================================================== */
.gpt-msg .gm-av{overflow:hidden;padding:0}
.gpt-msg .gm-av img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%}


/* ==========================================================================
   BLOG SEARCH (DP, 2026-07-27)
   Additive block. Search sits in the SAME row as the topic pills and narrows
   the same grid, live, as you type. Nothing here restructures the existing
   .np-cats or .np-pill components: .np-cats simply becomes a flex child of a
   new .np-toolbar wrapper, and every pill rule still applies unchanged.
   Delete this block and the ONE `.np-toolbar` wrapper in build-blog.mjs and
   the old row returns exactly as it was.
   ========================================================================== */
.np-toolbar{display:flex;align-items:flex-start;gap:16px;margin:0 0 28px}
/* the pills keep their own wrapping and give up width to the field last */
.np-toolbar .np-cats{flex:1 1 auto;min-width:0;margin:0}
/* 340px is not arbitrary: it is the width at which the placeholder sentence
   stops truncating at 14.4px. A clipped prompt reading "Try meta ad..." looks
   broken, so the field is sized to its own copy. */
.np-search{position:relative;flex:0 0 340px;display:flex;align-items:center}
.np-search .np-s-i{position:absolute;left:15px;width:17px;height:17px;
  color:var(--text-3);pointer-events:none;transition:color var(--t-fast) var(--ease)}
.np-search input{width:100%;min-height:44px;appearance:none;
  font-family:inherit;font-size:14.4px;font-weight:500;color:var(--text-1);
  background:var(--card-grad);border:1px solid var(--line);border-radius:100px;
  padding:10px 40px 10px 41px;
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
.np-search input::placeholder{color:var(--text-3);
  /* the placeholder is a full sentence and the field is narrow, so let it
     truncate rather than clip mid-letter */
  text-overflow:ellipsis}
.np-search input:hover{border-color:var(--line-strong)}
.np-search input:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft)}
.np-search input:focus + .np-s-x{color:var(--text-2)}
.np-search:focus-within .np-s-i{color:var(--accent)}
/* Safari draws its own clear button on type=search and it lands on top of ours */
.np-search input::-webkit-search-cancel-button,
.np-search input::-webkit-search-decoration{-webkit-appearance:none;appearance:none}
.np-s-x{position:absolute;right:6px;display:flex;align-items:center;justify-content:center;
  width:32px;height:32px;border:0;border-radius:50%;background:none;cursor:pointer;
  color:var(--text-3);font-size:13px;line-height:1;
  transition:color var(--t-fast) var(--ease),background var(--t-fast) var(--ease)}
.np-s-x:hover{color:var(--accent);background:var(--field-bg)}

/* Tablet down: the field takes the full width and sits UNDER the pills, so the
   pill row never gets squeezed into a two-line stub next to a tiny input. */
@media (max-width:900px){
  .np-toolbar{flex-direction:column;gap:12px}
  .np-toolbar .np-cats{width:100%}
  .np-search{flex:1 1 auto;width:100%}
}

/* Phone: the placeholder sentence does not fit in 375px, so ui.js swaps in a
   short one. Type stays at 16px because anything smaller makes iOS zoom the
   whole page the moment the field takes focus. */
@media (max-width:720px){
  .np-search input{font-size:16px}
}


/* ==========================================================================
   ACTIVE NAV PILL, STRENGTHENED (DP, 2026-07-27)
   Additive block. Delete it and the original faint pill returns.

   The pill already existed and shipped on every page. The problem was that it
   barely read as anything in LIGHT theme: `background:var(--glass)` is #FFFFFF,
   which is the same white as the bar behind it, so the only thing marking the
   current page was a 12% hairline. It looked like an outline, not the "circular
   box" it is meant to be. Dark theme was already fine, so it is left nearly
   alone and only gains a touch of edge.

   The fix is separation, not decoration: a fill that differs from the bar, a
   border you can actually see, and full-strength ink.
   ========================================================================== */
.navlinks a.on{
  color:var(--text-1);
  border-color:var(--line-strong);
  background:var(--glass-hi);
  font-weight:700;
}
[data-theme="light"] .navlinks a.on{
  /* a real fill against the white bar, plus a soft lift so the box has depth */
  background:#F1F1EC;
  border-color:rgba(10,10,10,.22);
  box-shadow:0 1px 2px rgba(10,10,10,.06);
}
/* hover must still out-rank the active state, or the current page feels dead */
.navlinks a.on:hover{border-color:var(--accent);color:var(--accent)}

/* The phone menu is a stacked sheet, not a bar, so a pill there reads oddly.
   It keeps the existing soft rectangle and only gains a clearer edge. */
@media (max-width:900px){
  .navlinks a.on{border-radius:12px;background:var(--accent-soft);color:var(--accent);border-color:var(--line-strong)}
  [data-theme="light"] .navlinks a.on{background:var(--accent-soft);color:var(--accent-ink);box-shadow:none}
}


/* ==========================================================================
   CENTRED PAGE HEROES (DP, 2026-07-27, extended to about + work-with-me 2026-07-28)
   Additive block. Remove it plus the `hero-centred` and `h1-3a` classes in
   the pages and the old left-aligned heroes return.

   THE PROBLEM DP REPORTED: the home hero was left aligned while every section
   under it is centred, so the page changed its mind halfway down and the eye
   had to reset. Fixing it by centring the hero rather than left-aligning the
   rest, because the rest of the page is already consistent.

   SCOPED BY CLASS, NOT BY ELEMENT. `.page-hero` is shared by every page hero.
   Only the pages carrying `.hero-centred` move, which is now home, about and
   work-with-me. The BLOG hero stays left aligned on purpose: it sits above a
   left-aligned toolbar and card grid, so centring it would create the same
   mismatch this block exists to remove.

   THE HEADLINE is the 3A thesis, so it now reads as three rows with the three
   A-words carrying the weight and the accent. That is the whole positioning in
   one glance instead of a paragraph that happens to wrap.
   ========================================================================== */
.hero-centred{text-align:center}
.hero-centred .lead{margin-left:auto;margin-right:auto}
.hero-centred .hero-ctas{justify-content:center}

/* CENTRE THE BOXES, NOT JUST THE TEXT. This is the bit that was wrong on the
   first pass and DP spotted it: `text-align:center` centres the words INSIDE
   each block, but `.page-hero h1` and `.page-hero .lead` carry `max-width`, so
   those blocks were still sitting hard left inside a wider wrap. The headline
   therefore centred on its own 900px box and landed about 140px left of the
   lead and the buttons, which is exactly the awkward look he described.
   `.hero-centred h1` beats `.page-hero h1` on specificity, so the auto margins
   here actually apply. Do not drop the selector back to `.h1-3a`, which loses
   to `.page-hero h1` and silently reintroduces the offset. */
.hero-centred h1,
.hero-centred .lead{margin-left:auto;margin-right:auto}

/* one clause per row, so the three A's stack instead of wrapping at random */
.h1-3a{font-weight:500}
.h1-3a span{display:block}
/* the three words that carry the thesis. Gradient text, which is the site's
   accent treatment: signal yellow on dark, near-black on light. */
.h1-3a b{font-weight:800;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent}

/* Phones: DP asked for everything centred here too, and the stacked full-width
   buttons already centre themselves. Tighten the line spacing a touch, because
   three short rows at the phone size otherwise read as a gappy list. */
@media (max-width:720px){
  .hero-centred h1{line-height:1.14}
  .hero-centred .eyebrow{margin-left:auto;margin-right:auto}
}

/* LIGHT THEME FIX for the three A-words, caught on the first render.
   `--grad` is a yellow gradient on dark, which is why AI / Automation / Ads
   glow there. In LIGHT it is `#0A0A0A -> #6A6A64`, so each emphasised word
   FADED OUT TO GREY while the plain words next to it stayed solid black. The
   emphasis was pointing the wrong way: the three words that carry the whole
   thesis looked weaker than "to build".
   Light therefore drops the gradient entirely: solid full-strength ink on the
   three words, and the rest of the line steps back to secondary. Dark keeps the
   gradient, because there it genuinely reads as the accent. */
[data-theme="light"] .h1-3a{color:var(--text-2)}
[data-theme="light"] .h1-3a b{
  background:none;-webkit-background-clip:border-box;background-clip:border-box;
  color:var(--text-1);-webkit-text-fill-color:var(--text-1)}


/* ==========================================================================
   FILLED-CARD PILL, CONTRAST FIX (DP, 2026-07-28)
   Additive block. Delete it and the old white pill returns.

   `.gcard.fill-card .g-price` was set to `color:#FFFFFF`, i.e. white text on
   the signal-yellow card. Measured against the card's own gradient that is
   1.27:1 to 1.88:1, where the accessible minimum for small text is 4.5:1. It
   was effectively unreadable, and DP spotted it.

   It was also the ONE element inside a filled card not following the rule the
   rest of the block already sets: everything on the yellow card takes
   `--fill-ink` / `--fill-muted`, which is near-black. Black on that same
   gradient measures 10.6:1 to 15.6:1.

   The pill keeps its shape. Only the ink and the tint flip from white to dark,
   so it now reads as a chip stamped ON the yellow rather than a ghost floating
   over it.
   ========================================================================== */
.gcard.fill-card .g-price{
  color:var(--fill-ink);
  border-color:rgba(0,0,0,.26);
  background:rgba(0,0,0,.07);
}


/* ==========================================================================
   IN-ARTICLE FIGURES, the illustrated-guide format (2026-07-28)
   Additive block. Delete it and articles return to the old figure styling,
   which is still sitting further up this file. Nothing here is destructive.

   WHY IT WAS NEEDED
   `.prose-fig img` was written for stock photography and carried
   `aspect-ratio:16/9;object-fit:cover`. Every picture in this new format is a
   SCREENSHOT of a real product page, and the source shots are 3200x2040, which
   is 1.57:1, not 1.78:1. Under the old rule the browser cropped roughly 11% off
   the top and bottom of every one of them, which on a screenshot means slicing
   the header off the app. The image now keeps its own shape.

   THE FRAME IS THE POINT
   These are dark screenshots and the site's DEFAULT theme is near-black. With
   no frame a dark screenshot bleeds into the page and stops reading as a
   picture. So there is a visible border, a rounded corner and a small inner
   inset ring, which also stops the black plate from touching the caption bar.
   On light the same frame reads as a card, and the shadow is only turned on
   there because a shadow under black on black is invisible work.

   PHONE SHOTS
   `.fig-phone` is a portrait screenshot (roughly 1:2). At full column width one
   would be over 1,400 pixels tall and push the next paragraph off the screen,
   so it is capped and centred on its own plate.
   ========================================================================== */
.prose-fig{
  margin:34px 0;
  background:var(--card-grad);
  border:1px solid var(--line);
  border-radius:16px;
  overflow:hidden;
}
[data-theme="light"] .prose-fig{box-shadow:0 6px 22px rgba(10,10,10,.07)}

/* The crop override: real shape, no cover. The RATIO IS NOT SET HERE. The
   generator writes `style="aspect-ratio:W/H"` on every figure image instead,
   because `aspect-ratio:auto` in a stylesheet also discards the ratio the
   browser derives from the width and height attributes, which collapses every
   lazy image to a one pixel box until it loads. Do not add a ratio back here. */
.prose-fig img{
  display:block;
  width:100%;
  height:auto;
  object-fit:fill;
  border-bottom:1px solid var(--line-soft);
}

/* the caption is content, not a label, so it gets read-able type and sits on a
   slightly recessed bar so it never looks like part of the screenshot */
.prose-fig figcaption{
  padding:13px 18px 14px;
  font-size:14.5px;
  line-height:1.6;
  color:var(--text-3);
  border-top:0;
}

/* portrait phone screenshot. The plate is padded so the phone floats rather
   than filling the frame edge to edge. */
.prose-fig.fig-phone{
  padding:22px 0 0;
  text-align:center;
}
/* width is set, not `auto` with a max-width. On a replaced element `width:auto`
   resolves to the NATURAL width, which is zero until the file arrives, so a
   lazy phone shot would reserve nothing and the page would jump when it landed. */
.prose-fig.fig-phone img{
  width:min(300px,72%);
  margin:0 auto;
  border-bottom:0;
  border-radius:12px;
}
.prose-fig.fig-phone figcaption{
  margin-top:20px;
  border-top:1px solid var(--line-soft);
  text-align:left;
}

@media (max-width:720px){
  .prose-fig{margin:26px 0;border-radius:13px}
  .prose-fig figcaption{padding:11px 14px 12px;font-size:13.6px}
  .prose-fig.fig-phone{padding:16px 0 0}
  .prose-fig.fig-phone img{width:min(230px,66%)}
}


/* ==========================================================================
   CONTRAST SWEEP, BOTH THEMES (DP, 2026-07-28)
   Additive block. Delete it and the old values return. Nothing is restructured.

   DP reported one instance: the CURRENT PAGE in the phone menu was yellow text
   on a pale yellow fill and unreadable. He then asked for the same class of
   error to be found everywhere rather than patched where it was visible, so
   every page was measured in both themes, at desktop and phone width, with the
   menu, the topic sheet and the table of contents opened. Thirty one distinct
   failures came back and they had exactly TWO causes, both fixed here.

   ------------------------------------------------------------------ CAUSE 1
   `--text-3`, the muted ink, failed the AA minimum for small text in BOTH
   themes. Measured against the surfaces it actually sits on:
     light  #8C8C86 on #FAFAF7  =  3.23:1   (needs 4.5)
     dark   #6E6E66 on #131313  =  3.61:1   (needs 4.5)
   It carries dates, read times, the author role, table headers, breadcrumbs,
   result counts, figure captions and the footer line, so this was most of the
   small print on the site sitting under the line. The new values measure 4.8:1
   and 5.3:1 against those same worst-case surfaces, and still read as clearly
   secondary next to `--text-2`.

   Muted is a HIERARCHY, not a licence to be unreadable. If you retune these,
   measure against the CARD colour, not the page colour: the card is the paler
   surface on light and the lighter one on dark, so it is always the worse case.

   ------------------------------------------------------------------ CAUSE 2
   `.navlinks a.on` on light, in the phone menu. It set `color:var(--accent-ink)`
   on a `--accent-soft` background. That looks reasonable until you read what
   the token is FOR: `--accent-ink` is the ink that sits ON the accent, and on
   light the accent is a BLACK button, so `--accent-ink` is yellow lettering.
   Used as text on a pale yellow fill it measured 1.30:1. This is the same
   mistake as the filled-card price pill above: a token named for one job used
   in another. The rule now takes `--text-1`, which is 16:1 on that fill.
   ========================================================================== */
/* THE BLUE RESKIN RE-TUNED THESE, 2026-07-29. They were #82827A / #6F6F6A,
   warm greys chosen to clear AA against the Gold-Noir card. The new cards are
   cooler and slightly different in value, and these are what carry dates, read
   times, the author role, captions and the footer, so they were re-measured
   rather than assumed. NOTE FOR ANYONE EDITING THE TOKEN BLOCKS AT THE TOP:
   this block overrides them, which is why a change up there appeared to do
   nothing. Change it HERE. */
:root{ --text-3:#8E939C; }
[data-theme="light"]{ --text-3:#69707C; }

@media (max-width:900px){
  [data-theme="light"] .navlinks a.on{color:var(--text-1)}
}


/* ==========================================================================
   THE BOOKING FLOW: /book, /thank-you, /a-message-from-pratik (2026-07-28)
   Additive block. Delete it plus the three pages and nothing else notices.

   DP asked for a native booking surface so calldp.com/book is no longer a
   separate site. Three pages share this block:
     book.html                   the VSL plus the eight qualifying questions
     thank-you.html              after the request, with the locked priority CTA
     a-message-from-pratik.html  where the polite-no email sends people

   The whole design brief for these is FEWER DECISIONS. One hook, one video,
   one button, then a form where seven of the eight questions are a single tap.
   ========================================================================== */

/* ---------------------------------------------------- the VSL hero ---- */
.vsl-hero{padding:56px 0 76px;text-align:center}
.vsl-hero h1{font-size:clamp(30px,5.2vw,52px);font-weight:800;letter-spacing:-.035em;line-height:1.08;
  margin:16px auto 0;max-width:16ch}
/* Emphasised words in a heading inherit a gradient-text treatment elsewhere in
   this stylesheet (background-image + background-clip:text). On this hero the
   em is the quiet half of the sentence, not the loud half, so the gradient is
   switched off EXPLICITLY rather than left to whichever rule happens to win on
   specificity. Relying on that has broken this codebase before. */
.vsl-hero h1 em{font-style:italic;font-weight:500;
  background:none;-webkit-background-clip:border-box;background-clip:border-box;
  color:var(--text-2);-webkit-text-fill-color:var(--text-2)}
.vsl-hero .lead{margin:18px auto 0;max-width:62ch;font-size:clamp(16.5px,2vw,19.5px);color:var(--text-2);line-height:1.62}
.vsl-hero .eyebrow{margin-left:auto;margin-right:auto}

/* the video. It is the point of the page, so it gets the width and a real
   frame rather than sitting loose on the background. */
.vsl-video{margin:34px auto 0;max-width:820px}
.vsl-video .vid-open{width:100%;display:block;padding:0;background:none;border:0;cursor:pointer}
.vsl-video .vid-thumb{display:block;position:relative;border-radius:18px;overflow:hidden;
  border:1px solid var(--line);background:var(--card-grad)}
.vsl-video img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
[data-theme="light"] .vsl-video .vid-thumb{box-shadow:0 18px 44px -20px rgba(10,10,10,.4)}

.vsl-cta{margin:30px auto 0}
.vsl-cta .btn{min-width:min(320px,86vw)}
.vsl-note{margin:14px auto 0;font-size:14.6px;color:var(--text-3);max-width:44ch}

/* ---------------------------------------------------- the form ---- */
.qsec{padding:10px 0 92px}
.qsec .sec-head{margin:0 auto 30px}
.qsec .sec-head p{max-width:58ch;margin-left:auto;margin-right:auto;color:var(--text-2)}
.qform{max-width:760px;margin:0 auto;text-align:left}
.qgroup{margin:0 0 26px}
.qlabel{display:block;font-family:"JetBrains Mono",monospace;font-size:13px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-2);margin:0 0 12px;line-height:1.5}
.qlabel .req{color:var(--accent);font-style:normal}
[data-theme="light"] .qlabel .req{color:#2E6BD3}
/* NAME COLLISION, CAUGHT IN TESTING. This hint was first written as
   class="opt", which is ALREADY a component in this stylesheet: a big
   selectable option card with a border, a card gradient and 16px of padding.
   A two-word hint inside a label picked all of that up and rendered as a box.
   Short generic class names in a 2,000 line stylesheet are taken. Namespace
   anything new, which is why everything on this form starts with q. */
.qlabel .qhint,.qhint{font-style:normal;font-weight:400;color:var(--text-3);
  letter-spacing:.06em;text-transform:none;border:0;padding:0;background:none}

/* the chips. A tap target, not a dropdown: a dropdown on a phone is a modal,
   a scroll and a second tap, and eight of those is why forms get abandoned. */
.qchips{display:flex;flex-wrap:wrap;gap:9px}
.qchips.col{flex-direction:column;align-items:stretch}
.qchip{appearance:none;cursor:pointer;font-family:inherit;font-size:15.6px;font-weight:600;
  color:var(--text-2);background:var(--field-bg);border:1px solid var(--line);
  border-radius:12px;padding:12px 16px;min-height:46px;text-align:left;
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.qchip:hover{border-color:var(--line-strong);color:var(--text-1)}
.qchip:active{transform:scale(.98)}
.qchip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* SELECTED. The filled card is the brand signature and it is identical in both
   themes on purpose, so the chosen chip borrows it: yellow panel, black ink. */
.qchip.on{background:var(--accent);color:var(--accent-ink);border-color:var(--accent);font-weight:700}
[data-theme="light"] .qchip.on{background:#2E6BD3;color:#FFFFFF;border-color:#1C4FA8}

/* a group the reader skipped */
.qchips.miss{outline:1px dashed var(--danger);outline-offset:6px;border-radius:8px}

.qdiv{height:1px;background:var(--line-soft);margin:30px 0 26px}
.field .req{color:var(--accent);font-style:normal}
[data-theme="light"] .field .req{color:#2E6BD3}

/* CONTRAST, caught by the sweep. --text-3 is tuned against the CARD colour,
   but a form field is darker still (the card plus a 5% white wash), and a
   placeholder on it measured 4.27:1 where small text needs 4.5. Placeholders
   get their own value on dark rather than moving --text-3 for the whole site,
   which is already correct everywhere else. */
[data-theme="dark"] .field input::placeholder,
[data-theme="dark"] .field textarea::placeholder{color:#8E8E86}

.qerr{margin:18px 0 0;padding:13px 15px;border-radius:12px;font-size:15px;font-weight:600;
  color:#fff;background:var(--danger);border:1px solid var(--danger)}
[data-theme="light"] .qerr{color:#fff}

.qsubmit{margin-top:22px;width:100%}
.qsubmit.is-busy{opacity:.7;pointer-events:none}
.qfoot{margin:14px 0 0;font-size:14.4px;color:var(--text-3);text-align:center}

/* ---------------------------------------------------- thank you ---- */
.ty-priority{max-width:620px;margin:40px auto 0;padding:24px 22px;text-align:left;
  background:var(--card-grad);border:1px solid var(--line);border-radius:18px}
.typ-head{display:flex;align-items:center;gap:11px;margin:0 0 10px;flex-wrap:wrap}
.typ-k{font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);border:1px solid var(--line-strong);border-radius:100px;padding:4px 11px}
[data-theme="light"] .typ-k{color:#2E6BD3}
.typ-head strong{font-size:19.5px;letter-spacing:-.02em}
.ty-priority p{color:var(--text-2);font-size:16px;margin:0 0 18px;line-height:1.6}
.ty-priority .btn{width:100%}
.typ-note{font-size:14px;color:var(--text-3);margin:14px 0 0}
.typ-note strong{color:var(--text-2)}

/* THE LOCKED BUTTON. It is a real disabled <button>, not a link to a checkout
   that does not exist yet, so it cannot be clicked through to a 404. When the
   $100 payment is real, swap the element for an <a> and drop .is-locked. */
/* The locked button is DISABLED, which WCAG exempts from contrast, but the
   whole reason DP wants it visible is the price. An unreadable "$100" does no
   marketing work at all, so it is lifted to a readable value anyway. */
.btn.is-locked{
  background:var(--field-bg);
  color:var(--text-2);
  border-color:var(--line);
  box-shadow:none;
  cursor:not-allowed;
  position:relative;
}
.btn.is-locked:hover{transform:none;color:var(--text-2);border-color:var(--line)}
.btn.is-locked::after{content:"🔒";margin-left:9px;font-size:14px;filter:grayscale(1);opacity:.75}

.ty-next{max-width:620px;margin:34px auto 0;text-align:left}
.ty-next h2{font-size:21px;letter-spacing:-.02em;margin:0 0 14px}
.ty-steps{margin:0;padding:0 0 0 20px;color:var(--text-2);font-size:16.2px;line-height:1.65}
.ty-steps li{margin:0 0 9px}
.ty-steps strong{color:var(--text-1)}
.ty-meanwhile{margin:20px 0 0;color:var(--text-2);font-size:16px;line-height:1.65}

/* ------------------------------------------- a message from pratik ---- */
.nf-body{max-width:820px;margin:44px auto 0;text-align:left}
.nf-body h2{font-size:clamp(23px,3vw,30px);letter-spacing:-.025em;margin:0 0 12px}
.nf-body > p{color:var(--text-2);font-size:16.8px;line-height:1.65;margin:0 0 26px;max-width:62ch}
.nf-cards{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.nf-card{display:block;text-decoration:none;padding:20px 19px;border-radius:16px;
  background:var(--card-grad);border:1px solid var(--line);
  transition:border-color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
.nf-card:hover{border-color:var(--line-strong);transform:translateY(-2px)}
.nf-k{display:block;font-family:"JetBrains Mono",monospace;font-size:11.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-3);margin:0 0 9px}
.nf-card strong{display:block;color:var(--text-1);font-size:18.5px;letter-spacing:-.02em;line-height:1.28;margin:0 0 8px}
.nf-card p{color:var(--text-2);font-size:15.4px;line-height:1.58;margin:0 0 14px}
.nf-go{font-size:14.6px;font-weight:700;color:var(--accent)}
[data-theme="light"] .nf-go{color:var(--text-1)}

.nf-when{margin:34px 0 0;padding:24px 22px;border-radius:18px;
  background:var(--plate);border:1px solid var(--line-strong)}
.nf-when h3{font-size:20px;letter-spacing:-.02em;margin:0 0 11px}
.nf-when p{color:var(--text-2);font-size:16.2px;line-height:1.65;margin:0 0 18px}
.nf-when strong{color:var(--text-1)}

@media (max-width:720px){
  .vsl-hero{padding:36px 0 54px}
  .vsl-hero h1{max-width:none}
  .vsl-video{margin-top:26px}
  .vsl-cta .btn{width:100%}
  .qsec{padding-bottom:64px}
  .qchip{font-size:15px;padding:11px 14px;min-height:44px}
  .nf-cards{grid-template-columns:1fr}
  .ty-priority,.nf-when{padding:20px 17px}
}


/* ---------- portrait VSL frame, BUILT AND NOT YET USED (2026-07-28) ----------
   Kept ready for the moment DP supplies his OWN vertical video for /book. The
   first file he sent turned out to be another creator's Instagram reel that he
   had downloaded as reference for a different task, so nothing was published
   and the page is back on the Loom placeholder.

   When his real file arrives: transcode to H.264 (the reference file was HEVC,
   which Chrome will not play), drop it in assets/video/, and swap the
   .vid-open button on book.html for a <video class="vsl-native" preload="none"
   poster="..."> inside .vsl-video.is-portrait. preload="none" plus a poster is
   what keeps a multi-megabyte file off the initial page weight. */
.vsl-video.is-portrait{max-width:none;display:flex;justify-content:center}
.vsl-native{
  display:block;
  width:min(340px,78vw);
  height:auto;
  aspect-ratio:720/1280;
  border-radius:18px;
  border:1px solid var(--line);
  background:#000;
  object-fit:cover;
}
[data-theme="light"] .vsl-native{box-shadow:0 18px 44px -20px rgba(10,10,10,.4)}
@media (max-width:720px){
  .vsl-native{width:min(300px,80vw)}
}

/* ==========================================================================
   LINKS INSIDE AN ANSWER CARD (added 2026-07-28)

   The answer card was built for the article template, where the `answer` field
   is plain text with at most a <strong>, so it never needed link styling and
   never got any. The "In one paragraph" entity block on about.html is the first
   answer card to carry links, and without this they inherited the paragraph
   colour exactly: same colour, no underline, normal weight. Visually and to a
   screen reader they were not links at all.

   This mirrors the `.prose a` treatment already used in article bodies rather
   than inventing a second link style. Scoped to .answer-card so it cannot leak
   into anything else, and additive: delete this block and only those two links
   lose their styling.
   ========================================================================== */
.answer-card a{
  color:var(--accent);
  font-weight:600;
  text-decoration:underline;
  text-underline-offset:2px;
  text-decoration-thickness:1px;
  text-decoration-color:color-mix(in srgb, var(--accent) 45%, transparent);
}
.answer-card a:hover{text-decoration-color:var(--accent)}

/* ---------- BUTTONS NEVER UNDERLINE (DP, 2026-08-05) ----------
   Base a{} already drops the underline, but .prose a{} adds one for inline body
   links and it was bleeding onto the in-article CTA button (an a.btn inside the
   prose). This keeps every button clean, in prose and everywhere else. */
a.btn, a.btn:hover,
a[class*="btn-"], a[class*="btn-"]:hover,
.prose a.btn, .prose a.btn:hover,
.prose-cta .btn, .prose-cta .btn:hover{ text-decoration:none }

/* ---------- MOBILE POLISH (DP, 2026-08-05) ----------
   1. FAQ box sits further below its heading (it was hugging the hook).
   2. Hooks wrap evenly so a black + blue split breaks at the colour boundary
      instead of orphaning the first blue word on line one. Short hooks stay on
      one line because balancing never forces a wrap that is not needed. */
.faq{margin-top:26px}
@media (min-width:721px){.faq{margin-top:34px}}
.page-hero h1,.sec-head h2,.band h2{text-wrap:balance}

/* Section kickers removed site-wide (DP, 2026-08-05): the small "dash-and-label" lines
   above section headings were unnecessary. Hidden, not deleted, so restoring is
   removing this one rule. */
.sec-kicker{display:none}

/* ---------- THEME-INVERTED COMMAND-CENTER MOCKUPS (DP, 2026-08-05) ----------
   The flagship nine-step guide carries `ccfig` figures that ship BOTH renders
   of each command-center screen. DP's rule: a LIGHT page shows the DARK mockup,
   a DARK page shows the LIGHT mockup, so the screenshot always pops off the
   paper instead of blending into it.

   The blog theme lives on <html data-theme>, key `dp-theme`, and the inline
   head script stamps it before first paint, so KEY OFF data-theme, never
   prefers-color-scheme (the OS setting is not what the reader chose here).

   Both images sit inside the .prose-fig card and get its border, radius and
   shadow for free. Only one paints: the other is display:none, so there is no
   double box and no layout jump. Delete this block and both images would show;
   nothing here is destructive to the rest of the figure system. */
.cc-fig .cc-light{display:none}
[data-theme="dark"] .cc-fig .cc-dark{display:none}
[data-theme="dark"] .cc-fig .cc-light{display:block}

/* ---------- BRAND FACE (DP, 2026-08-05) ----------
   DP's smiling photo, circular, before the wordmark on every page, as constant
   brand recall against his name. The photo already sits on his signature yellow,
   so a thin yellow ring finishes it as a brand token. This is the ONE place
   yellow returns to the otherwise-blue system, on DP's explicit call, scoped to
   the personal mark only; the UI (buttons, links, headings) stays blue.
   Delete this block and the topbar falls back to the plain wordmark. */
.brand-face{
  width:40px;height:40px;flex:none;border-radius:50%;
  background:#FFD60A;
  box-shadow:0 0 0 2px #FFD60A, 0 1px 3px rgba(10,10,10,.28);
  overflow:hidden;
}
.brand-face img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
/* the dark-theme rule inverts .brand img (for a monochrome logo mark); the photo
   must never be inverted, so pin it back in BOTH themes. */
html .brand .brand-face img,
html:not([data-theme="light"]) .brand .brand-face img{filter:none !important;height:100%;width:100%}
@media (max-width:720px){.brand-face{width:33px;height:33px}}

/* ---------- TEXT-COLUMN TABLES (DP, 2026-08-05) ----------
   The base .price-table makes the LAST column nowrap and right-aligned, which
   is right for a short money figure ("$3,240") and wrong for a column of prose.
   A table authored with `variant:'text'` gets `table-text`, and on DESKTOP its
   cells wrap and left-align so a long sentence fits the reading column instead
   of forcing the whole box to scroll sideways. Fixed layout with two narrow
   label columns keeps the wide column predictable.

   SCOPED to min-width:721px on purpose. Below that the phone STACKED layout
   (further up this file) already turns every row into its own card with no
   horizontal scroll, so it must not be overridden here. Delete this block and
   text tables simply fall back to the old sideways-scroll behaviour. */
@media (min-width:721px){
  .prose-table.table-text table.price-table{table-layout:fixed;min-width:0}
  .prose-table.table-text .price-table th,
  .prose-table.table-text .price-table td{white-space:normal;text-align:left;vertical-align:top}
  .prose-table.table-text .price-table th:last-child,
  .prose-table.table-text .price-table td:last-child{
    text-align:left;white-space:normal;
    font-family:"Plus Jakarta Sans",ui-sans-serif,system-ui,-apple-system,sans-serif;
    font-size:15.5px;font-weight:400;color:var(--text-2);
  }
  .prose-table.table-text .price-table th:first-child,
  .prose-table.table-text .price-table td:first-child{width:16%}
  .prose-table.table-text .price-table th:nth-child(2),
  .prose-table.table-text .price-table td:nth-child(2){width:17%}
}
