/* ============================================================================
   BetterBreaks — shared stylesheet
   Tokens and rules come from betterbreaks.app/BRIEF.md. Never write a raw hex
   outside :root, and never a font-size that is not on the scale below.
   ========================================================================== */

/* The hidden attribute only works through the UA sheet's display:none, so any
   rule of ours that sets display beats it — .acct-actions{display:flex} did,
   which put the Admin card in front of every signed-in user for a week. JS
   toggles `hidden` all over this site; this is what makes that mean anything. */
[hidden]{display:none !important}

:root{
  /* ground and ink */
  --ground:#FBFFF0; --surface:#FFFFFF; --ink:#18291D; --ink-muted:#4C5A4E;
  --line:#E1EAD6;

  /* greens: the anchor */
  --forest:#1E3D2F; --forest-2:#2F5A42; --sage:#6E9478; --mint:#DCEFE0;

  /* on the dark band */
  --on-forest:#F1F6EA; --on-forest-muted:#A9BFAF; --forest-line:#33553F;

  /* accents. ember is actions only, amber and sky are stat numerals only */
  --ember:#E8784A; --ember-dark:#D96534; --amber:#D4A93C; --sky:#5AA9D6;

  /* the hero video's painted wall, sampled from the footage. tracks the file,
     not the palette, so it is pinned separately. see README.md */
  --wall:#FCF4E6;

  /* shape */
  --r-xs:6px; --r-card:16px; --r-media:24px; --r-page:40px; --r-pill:999px;

  /* type — one family everywhere (Raj, 2026-09-17). Display and body separate
     on weight and tracking, not on face, so the tokens stay meaningful. */
  --display:"Jost","Avenir Next",system-ui,sans-serif;
  --body:"Jost",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;

  /* space, 4px grid */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px;
  --s8:72px; --s9:120px;

  /* type scale. The display sizes are BRIEF.md §3; the small sizes are the
     ones this site already used, named so a new rule cannot invent a 13.5.
     --fs-body drops to 16px under 760px, in the media query below. */
  --fs-xs:12px; --fs-sm:14px; --fs-md:15.5px; --fs-base:16px; --fs-body:17px;
  --fs-lg:1.18rem; --fs-h3:1.3rem;
  --fs-h2:clamp(2rem,4.2vw,3.2rem); --fs-h1:clamp(2.8rem,6vw,4.8rem);
  /* display steps for numerals, prices, plan names and interior-page heads.
     The home hero's own sizes and timings are not on this scale on purpose. */
  --fs-xl:1.5rem; --fs-2xl:2rem; --fs-3xl:2.5rem; --fs-4xl:2.75rem;
  --fs-num:clamp(3rem,6vw,4.4rem);
  --fs-h1-page:clamp(2.4rem,5vw,3.8rem); --fs-lede-page:clamp(1.12rem,1.7vw,1.35rem);

  /* layout */
  --wrap:1200px; --gutter:28px; --tap:44px;

  /* shadows, tinted with --ink rather than black so they sit in the palette.
     Named by what casts them; there is no shadow on the cream ground, cards
     there take a --line border instead. */
  --shadow-nav:0 12px 32px -16px rgba(24,41,29,.30);
  --shadow-flag:0 6px 16px -8px rgba(12,26,18,.5);
  --shadow-card-dark:0 2px 6px rgba(6,14,9,.28),0 28px 56px -12px rgba(6,14,9,.6);
  --shadow-card-raised:0 3px 8px rgba(6,14,9,.32),0 40px 80px -12px rgba(6,14,9,.72);
  --shadow-cta:0 10px 22px -12px rgba(217,101,52,.42);
  --shadow-cta-hover:0 14px 28px -12px rgba(217,101,52,.52);

  /* motion */
  --t-fast:.15s ease; --t-base:.2s ease; --t-slow:.32s ease;
  --t-nav:.62s cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.22,.9,.28,1);

  /* focus */
  --focus:3px solid var(--ember);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--ground);color:var(--ink);
  font-family:var(--body);font-size:var(--fs-body);line-height:1.65;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img,video{max-width:100%;display:block}
a{color:inherit}
p{margin:0}
:focus-visible{outline:var(--focus);outline-offset:3px;border-radius:var(--r-xs)}

/* Gated per BRIEF.md §3. Anything that moves must survive this being on. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *{animation:none!important;transition:none!important}
}

/* ---------- type scale ---------- */
/* Jost is geometric and optically light, so display sizes carry more weight and
   tighter tracking than a serif would need to hold the same presence. */
h1,h2,h3{font-family:var(--display);font-weight:600;margin:0;letter-spacing:-0.025em}
h1{font-size:var(--fs-h1);line-height:1.02;font-weight:700;letter-spacing:-0.035em}
h2{font-size:var(--fs-h2);line-height:1.06;font-weight:700;letter-spacing:-0.03em}
h3{font-size:var(--fs-h3);line-height:1.3;font-weight:600;letter-spacing:-0.015em}
.lede{font-size:var(--fs-lg);color:var(--ink-muted);max-width:34ch}
.prose{max-width:68ch;color:var(--ink-muted)}
.eyebrow{
  font:600 var(--fs-xs)/1 var(--body);letter-spacing:.16em;text-transform:uppercase;
  color:var(--forest-2);margin-bottom:var(--s4);
}

/* ---------- layout ---------- */
/* Gutter grows under a notch in landscape; env() is 0 everywhere else. */
.wrap{
  max-width:var(--wrap);margin:0 auto;
  padding-inline:max(var(--gutter),env(safe-area-inset-left)) max(var(--gutter),env(safe-area-inset-right));
}
.sec{padding:var(--s9) 0}
@media (max-width:760px){ :root{--fs-body:16px} .sec{padding:var(--s8) 0} }

/* The rounded page. A band sits flush on the section above and curves up over
   it. This is the freedom.to detail Raj asked for; the flush seam is what sells
   it, so never add a margin above a .band. */
.band{border-radius:var(--r-page) var(--r-page) 0 0;position:relative;z-index:1}
.band-forest{background:var(--forest);color:var(--on-forest)}
.band-forest .lede,.band-forest .soft{color:var(--on-forest-muted)}
.band-forest .eyebrow{color:var(--on-forest-muted)}
.band-mint{background:var(--mint)}
@media (max-width:760px){ .band{border-radius:var(--r-media) var(--r-media) 0 0} }

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:10px;
  font:600 var(--fs-base)/1 var(--body);text-decoration:none;
  border-radius:var(--r-pill);padding:17px 28px;border:0;cursor:pointer;min-height:var(--tap);
  transition:background var(--t-base),transform var(--t-fast),box-shadow var(--t-base);
}
/* The gradient from betterbreaks-hero.html's "Download for Mac" button, kept as
   Raj asked on 2026-09-17. The white label that came with it did not survive:
   it measured 2.14:1 at the amber end, failed the smoke test on every page, and
   read cheap next to the rest of the palette. --ink on the same gradient holds
   5.25:1 and is what warm CTAs use when they are done well. (2026-09-23) */
.btn-primary{
  background:linear-gradient(100deg,#F0A128,#F0705C);
  color:var(--ink);
  box-shadow:var(--shadow-cta);
}
.btn-primary:hover{box-shadow:var(--shadow-cta-hover)}
.btn-primary:active{transform:translateY(1px)}
.btn-ghost{background:transparent;color:inherit;border:1.5px solid var(--line);padding:15.5px 26px}
.btn-forest{background:var(--forest);color:var(--on-forest)}
.btn-forest:hover{background:var(--forest-2)}
.band-forest .btn-ghost{border-color:var(--forest-line)}
.band-mint .btn-ghost{border-color:var(--sage)}
.btn-ghost:hover{border-color:var(--sage)}
.btn-text{
  display:inline-flex;align-items:center;gap:8px;font-weight:600;
  text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1.5px;
}
.btn svg,.btn-text svg{width:17px;height:17px;flex:none}
.cta-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s3) var(--s5)}
.micro{font-size:var(--fs-sm);color:var(--ink-muted);margin-top:var(--s4)}
.band-forest .micro{color:var(--on-forest-muted)}

/* ---------- nav ---------- */
/* Two headers, the way freedom.to does it, rather than one bar that morphs.
   The flat bar is in normal flow and scrolls away with the page. The pill is
   a second copy — fixed, a definite width, parked above the viewport — that
   slides down once the flat bar has gone. Nothing resizes, so there is no
   intrinsic width to tween and never a frame with both on screen. Their pill
   is a duplicate header in the markup; ours is cloned from the bar by
   js/site.js at load, so the HTML still carries one nav. Pricing keeps its
   own fixed forest bar and opts out (.top-dark, css/pricing.css). */
.nav{position:relative;z-index:40;background:transparent}
/* Bar and pill share a width and an inner padding, so the pill arrives on the
   same footprint the bar was standing on and only y and the chrome change.
   At --wrap (1200) the bar was 300px wider than the pill that replaced it, and
   the hand-off read as a jump rather than a slide (Raj, 2026-09-23). */
.nav .wrap{
  display:flex;align-items:center;gap:var(--s5);position:relative;
  width:min(900px,calc(100% - 2*var(--gutter)));height:70px;
  padding-inline:20px 12px;
}

/* The pill moves on transform alone, like freedom.to's translateY(-120px) to
   0 at top:24px. Its width is a length, not max-content, so it is settled
   before the slide starts. */
.nav-pill{
  position:fixed;top:16px;left:0;right:0;z-index:50;
  pointer-events:none;
  transform:translateY(calc(-100% - 16px));
  transition:transform var(--t-nav);
}
.nav-pill.is-open{transform:none}
.nav-pill .wrap{
  pointer-events:auto;height:60px;
  background:color-mix(in srgb,var(--surface) 86%,transparent);
  backdrop-filter:saturate(1.4) blur(16px);
  -webkit-backdrop-filter:saturate(1.4) blur(16px);
  border-radius:var(--r-pill);
  box-shadow:var(--shadow-nav),0 0 0 1px var(--line);
}
@media (prefers-reduced-motion:reduce){ .nav-pill{transition:none} }
.brand{
  display:flex;align-items:center;gap:10px;text-decoration:none;
  font-family:var(--display);font-weight:700;font-size:var(--fs-h3);letter-spacing:-0.025em;
}
/* The mark ships as two SVG files rather than inline markup: the path is 14KB,
   and inlining it in a nav and a footer on seven pages would cost more than the
   two cached requests do. Forest on the cream nav, mint on the forest footer. */
/* The two lockup files are cropped to the ink, so the box is the mark: the
   gap below is the real optical gap, and the mark aligns flush left with the
   text under it. The icon and favicon files keep their padding. */
.brand img{width:auto;height:30px;flex:none;display:block}
/* Brand left, links centred, action right. Centring was wrong at 1200, where
   the four links filled a third of the bar and left a run of nothing either
   side; at 900 the row is dense enough that the centre holds. The auto margins
   do the centring: brand (151px) and action (162px) are near enough the same
   width that the block lands within a few px of true centre, and it stays
   centred when the auth link changes from Log in to Account. */
.nav nav{display:flex;gap:var(--s1);margin-inline:auto}
.nav nav a{
  text-decoration:none;font-weight:500;font-size:var(--fs-md);color:var(--ink-muted);
  /* Pill hit areas, like freedom.to's 100px nav links — --r-pill is already the
     token for this, so a 10px rect was the odd one out. */
  padding:9px 15px;border-radius:var(--r-pill);
}
.nav nav a:hover{color:var(--ink);background:color-mix(in srgb,var(--mint) 55%,transparent)}
.nav nav a[aria-current="page"]{color:var(--forest);background:var(--mint)}
/* Account link sits apart from the page links, as on freedom.to. */
.nav nav .nav-auth{margin-left:var(--s3);color:var(--ink)}
.nav nav .nav-admin{color:var(--ember-dark);font-weight:600}
@media (max-width:880px){ .nav nav .nav-auth{margin-left:0;border-top:1px solid var(--line);margin-top:var(--s2);padding-top:var(--s3)} }
.menu-btn{
  display:none;margin-left:auto;background:none;border:1px solid var(--line);
  color:var(--ink);border-radius:var(--r-xs);padding:9px 14px;font:500 var(--fs-md) var(--body);min-height:var(--tap);
}
@media (max-width:880px){
  /* The dropdown hangs off the bar it belongs to, as a card: neither header is
     full-bleed any more, so a full-bleed sheet has no edge to continue. */
  .nav nav{
    display:none;position:absolute;top:calc(100% + 8px);left:0;right:0;flex-direction:column;
    margin-inline:0;
    background:var(--ground);padding:var(--s3) var(--s4) var(--s4);
    border:1px solid var(--line);border-radius:var(--r-card);box-shadow:var(--shadow-nav);
  }
  .nav nav.open{display:flex}
  .nav nav a{min-height:var(--tap);display:flex;align-items:center}
  .menu-btn{display:block}
  .nav .btn{display:none}
  /* The pill sits closer to the top here. */
  .nav-pill{top:8px}
}

/* ---------- hero ----------
   Light, not forest. The hero video's wall is painted cream and cannot be
   repainted, so the dark band lands on the stats section instead. */
.hero{position:relative;overflow:hidden;background:var(--wall)}
.hero-art{position:absolute;inset:0;z-index:0}
.hero-art video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:right top;transition:opacity .6s ease;
}
.hero-loop{opacity:0}
.hero-art.resting .hero-vid{opacity:0}
.hero-art.resting .hero-loop{opacity:1}
/* Recolours the flat left third of the painted wall so the copy sits on the
   page ground. Stops before 56%, where he enters frame. */
.hero-art::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(90deg,
    var(--ground) 0%,var(--ground) 20%,rgba(251,255,240,.82) 36%,rgba(251,255,240,0) 56%);
}
.hero .wrap{
  position:relative;z-index:2;min-height:min(76vh,720px);
  display:flex;align-items:center;padding-top:var(--s7);padding-bottom:var(--s8);
}
.hero-copy{max-width:660px}
.hero-copy h1{margin-bottom:var(--s5)}
.hero-copy .lede{margin-bottom:var(--s6);max-width:38ch}

/* ---------- headline / chain cross-fade ----------
   The headline stays in normal flow, so with JS off the hero still lays out from
   it. The chain is lifted out of flow and overlaid. Two earlier shapes failed:
   a shared grid cell sized to the taller state parked a hole under the shorter
   one, and clamping the container's height left the 235px headline row still
   driving where the chain painted, which put the chain on top of the lede.
   site.js sets the height to whichever state is on screen; see fitSwap(). */
.hero-swap{
  position:relative;margin-bottom:var(--s5);
  /* Moves with the incoming text rather than snapping ahead of it. */
  transition:height .9s cubic-bezier(.4,0,.2,1) .2s;
}
/* Slow-mo, matched to the word change: the incoming side runs .9s, the same
   duration a rotating word takes to arrive. The outgoing side still clears
   first — a symmetric cross-fade puts two different texts on screen at ~50% at
   once and reads as a double exposure. */
.swap{opacity:0;transition:opacity .55s ease;pointer-events:none}
.swap.is-on{opacity:1;pointer-events:auto;transition:opacity .9s ease .55s}
.hero-swap .chain{position:absolute;top:50%;left:0;transform:translateY(-50%)}
/* beats .hero-copy h1's bottom margin, which would reserve dead space */
.hero-copy .swap-head{margin:0}
/* Cap the measure. Without it the headline drops to 2 lines from 620px up while
   the chain stays at 4, leaving 64-72px of dead space in the headline state —
   worst at 900px. 19ch also just reads better than 564px of 45px type. */
.hero-copy .swap-head{max-width:19ch}

/* ---------- kinetic chain ----------
   Shown only while the idle typing clip is playing. One line: "Better", the
   paper plane, then a single word at the plane's nose that cycles Breaks ->
   Productivity -> Health -> Eyes. The plane silhouette is traced from
   nyracorp.com's paperplane.jpg, so it is the reference shape rather than an
   approximation of it (aspect 1.10 — blunt and chunky, not a thin dart). */
.chain{
  /* A lead line, then the climbing line under it. */
  display:flex;flex-direction:column;align-items:flex-start;
  margin:0;max-width:none;white-space:nowrap;
  font-family:var(--display);font-weight:700;
  /* "Better" + plane + "Productivity" is the widest the line ever gets. At
     4.4rem that measured 702px against a 660px column and, with nowrap, it just
     overflowed. 3.8rem keeps the longest word inside the column. */
  /* Capped at 3.6rem, not 3.8: at 3.8 the longest word ("Productivity") ran to
     x=890 at 1440, which is where the video's subject enters frame. */
  font-size:clamp(2.2rem,4.7vw,3.6rem);letter-spacing:-0.03em;line-height:1.05;
}
/* The row that carries the climb. The graphic rises out of this line, so the
   rise is reserved as padding above it. Measured off the asset: the trail's
   first dot sits at (0%, 92.1%) of the image box, the nose at (99.8%, 2.0%). */
/* One sentence over two lines: "Take a break for" / "Better -> <word>". At
   full size, not a small grey label — it is the subject of the line below, so
   it has to read as the same sentence. */
.chain-lead{display:block;color:var(--ink)}
/* The gap between the lead and this row is what the plane climbs through. It
   has to be tall enough for the word to sit at the nose without running into
   "for" — measured: at 0.5em they overlapped by 0.525em in both axes. */
.chain-line{display:flex;align-items:flex-end;gap:0;padding-top:1.2em}

/* nyracorp.com's .highlight treatment, copied exactly: the same four stops in
   the same order, the same 300% background-size and the same 8s shimmer.
   Tokens are theirs, from nyra-tech/style.css:71-77 —
   --grad-2 #A960EE, --grad-3 #FF5C87, --grad-4 #FFCB57, --grad-1 #80ECFF.
   One class, worn by the headline's key phrase and by the chain's "Better", so
   the two hero states carry the same mark — the way nyracorp highlights only
   "Grow Your Business" out of its headline. */
.hl,
.chain-fixed{
  background:linear-gradient(135deg,#A960EE,#FF5C87,#FFCB57,#80ECFF);
  background-size:300% 300%;
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;
  animation:shimmer 8s ease-in-out infinite;
}
@keyframes shimmer{
  0%,100%{background-position:0 50%}
  50%    {background-position:100% 50%}
}
@media (prefers-reduced-motion:reduce){ .hl,.chain-fixed{animation:none} }

/* Sized by height so the graphic tracks the type. The asset carries the trail,
   the loop and the plane, so the box is wide — 2.52:1. Raised so the trail's
   first dot sits at the top edge of the "r" in Better, the way nyracorp.com
   starts its trail at the top edge of the "s" in Business. */
.chain-plane{
  height:1.5em;width:auto;flex:none;
  /* Pulled left so the trail's first dot sits against the "r" rather than a
     fifth of an em off it — the opening dots are small, so any gap reads as a
     bigger one than it measures. Right margin holds the word off the nose. */
  margin-left:-0.04em;margin-right:0.2em;
  transform:translateY(-0.53em);
  /* nyracorp.com's planeColorShift, cadence and all. See the keyframes below. */
  animation:planeShift 16s ease-in-out infinite;
}
/* nyracorp.com's planeColorShift, copied exactly (read off the live site and
   confirmed against nyra-tech/assets/css/homepage.css). The asset is kept at its
   original blue for the same reason — the filter is tuned for that source, so
   recolouring first would land somewhere else entirely. */
@keyframes planeShift{
  0%,100%{filter:hue-rotate(20deg) saturate(1.5) brightness(1)}
  50%    {filter:hue-rotate(150deg) saturate(1.4) brightness(1.1)}
}
@media (prefers-reduced-motion:reduce){
  /* Not animation:none — the asset is nyracorp's original blue and only the
     filter colours it, so killing the animation leaves a blue plane on a green
     and ember page. Pin the 50% keyframe, which is the warm end of the cycle. */
  .chain-plane{animation:none;filter:hue-rotate(150deg) saturate(1.4) brightness(1.1)}
}

/* Lifted to the plane's nose: the word is where the climb arrives. */
.chain-words{display:inline-grid;color:var(--forest-2);transform:translateY(-1.475em)}
/* Transition values lifted verbatim from betterbreaks-hero.html's .rotator:
   the incoming word rises .28em and settles on a soft overshoot curve; the
   outgoing one leaves upward, faster, so the two never cross in the middle. */
.cw{
  grid-area:1/1;justify-self:start;white-space:nowrap;
  opacity:0;transform:translateY(.34em);
  transition:opacity .9s ease,transform 1.05s cubic-bezier(.22,.9,.28,1);
}
/* The outgoing word clears before the incoming one starts. Without the delay
   they share the cell for ~190ms and two different words are legible on top of
   each other — measured at 0.34/0.29 opacity, 94ms in. */
.cw.in{
  opacity:1;transform:translateY(0);
  transition:opacity .9s ease .26s,transform 1.05s cubic-bezier(.22,.9,.28,1) .26s;
}
.cw.out{
  opacity:0;transform:translateY(-.22em);
  transition:opacity .26s ease,transform var(--t-slow);
}

@media (max-width:620px){
  /* 1.9rem put "Better + plane + Productivity" at 308px in a 304px column at
     360px wide. The floor, not the vw term, was doing the overflowing. */
  .chain{font-size:clamp(1.72rem,8vw,2.6rem)}
  /* Sized by width here, not height. The old rule kept height:1.5em and added
     width:1.7em, which squashed the 2.52:1 asset to 1.13:1 — a crumpled plane
     with its trail folded up (measured 51x45 at 375px). At 2.2em wide the box
     is 0.87em tall, so the nose lands lower and the word comes down to meet it:
     nose = bottom - 0.53em - 0.98*0.87em, word centre = bottom - t - 0.525em,
     so t = 0.86em. Longest line at 390px: 84 + 68 + 6 + 161 = 319 in 334. */
  .chain-plane{width:2.2em;height:auto}
  .chain-words{transform:translateY(-0.86em)}
  /* The climb is shorter, so the gap it climbs through is too. 0.95em keeps
     the lifted word's box (1.91em above the bottom) inside the row. */
  .chain-line{padding-top:0.95em}
}

@media (max-width:880px){
  .hero{display:flex;flex-direction:column;background:var(--ground)}
  /* Under the copy, the video becomes a media block in the gutters: --r-media
     corners and a --line border, the same shape every other picture on the
     site takes. Full-bleed it read as a leftover strip, not a picture. */
  .hero-art{
    position:relative;order:2;height:auto;margin:0 var(--gutter) var(--s6);
    border-radius:var(--r-media);overflow:hidden;border:1px solid var(--line);
    background:var(--wall);
  }
  /* The plate is 2.8:1 because desktop crops it vertically; showing the whole
     plate on a phone gave a 134px ribbon, the left 55% of it blank wall and
     the subject 130px wide (measured at 375). A cover-fit box instead crops
     the blank wall off the left instead — he enters the frame at 56%, and
     a 3:2 box at 768 shows from 46%. Height is never cropped, so the stretch
     shots keep his arms. */
  .hero-art video{position:relative;height:auto;aspect-ratio:3/2;object-position:100% 50%}
  .hero-art .hero-loop{position:absolute;inset:0;height:100%}
  .hero-art::after{display:none}
  .hero .wrap{min-height:0;padding-top:var(--s7);padding-bottom:var(--s5)}
}
@media (max-width:620px){
  /* 4:3 on phones: at 375 the box shows the right 48% of the plate, which is
     him, the laptop, the window and the plant, with a hand's width of wall. */
  .hero-art video{aspect-ratio:4/3}
  .hero-art{margin-bottom:var(--s5)}
}

/* ---------- platform strip ---------- */
.strip{border-bottom:1px solid var(--line)}
.strip ul{
  list-style:none;margin:0;padding:var(--s5) 0;display:flex;flex-wrap:wrap;
  gap:var(--s3) var(--s7);justify-content:center;font-size:var(--fs-md);color:var(--ink-muted);
}
.strip li{display:flex;align-items:center;gap:9px}
.strip svg{width:17px;height:17px;color:var(--sage);flex:none}

/* ---------- stats ---------- */
.stat-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s7);
  margin-top:var(--s8);
}
@media (max-width:880px){ .stat-grid{grid-template-columns:1fr;gap:var(--s6)} }
.stat b{
  display:block;font-family:var(--display);font-weight:700;
  font-size:var(--fs-num);line-height:.95;letter-spacing:-0.03em;
}
.stat-amber b{color:var(--amber)} .stat-sky b{color:var(--sky)} .stat-ember b{color:var(--ember)}
.stat p{margin-top:var(--s3);max-width:30ch}
.src{
  display:inline-block;margin-top:var(--s3);font-size:var(--fs-sm);
  color:var(--on-forest-muted);text-decoration:underline;
  text-underline-offset:4px;text-decoration-thickness:1px;
}
.src:hover{color:var(--on-forest)}
.band-mint .src,.sec .src{color:var(--ink-muted)}
.band-mint .src:hover,.sec .src:hover{color:var(--ink)}
/* Restated after the .sec rule above, which is equally specific and would
   otherwise win on order and put --ink-muted on --forest at 1.63:1. */
.band-forest .src{color:var(--on-forest-muted)}
.band-forest .src:hover{color:var(--on-forest)}

/* ---------- steps (asymmetric on purpose, see BRIEF.md §4) ---------- */
.steps{display:grid;gap:var(--s7);margin-top:var(--s8)}
.step{display:grid;grid-template-columns:64px 1fr;gap:var(--s5);align-items:start}
.step-n{
  font-family:var(--display);font-size:var(--fs-2xl);font-weight:700;line-height:1;
  color:var(--sage);letter-spacing:-0.03em;
}
.step p{color:var(--ink-muted);margin-top:var(--s2);max-width:56ch}
@media (min-width:881px){
  .steps{grid-template-columns:repeat(3,1fr);gap:var(--s7)}
  .step:nth-child(2){margin-top:var(--s7)}
  .step:nth-child(3){margin-top:calc(var(--s7) * 2)}
}

/* ---------- modes table ---------- */
.tablewrap{overflow-x:auto;margin-top:var(--s7);border-radius:var(--r-card)}
table{border-collapse:collapse;width:100%;min-width:620px;background:var(--surface)}
th,td{text-align:left;padding:18px 22px;border-bottom:1px solid var(--line);font-size:var(--fs-md)}
thead th{
  font:600 var(--fs-xs)/1 var(--body);letter-spacing:.14em;text-transform:uppercase;
  color:var(--forest-2);background:var(--ground);
}
tbody th{font-family:var(--display);font-size:var(--fs-lg);font-weight:600;white-space:nowrap}
tbody tr:last-child th,tbody tr:last-child td{border-bottom:0}
td.num{font-variant-numeric:tabular-nums;color:var(--ink-muted);white-space:nowrap}

/* ---------- research tiles ---------- */
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5);margin-top:var(--s8)}
@media (max-width:880px){ .tiles{grid-template-columns:1fr} }
.tile{
  background:var(--surface);border-radius:var(--r-card);padding:var(--s6);
  display:flex;flex-direction:column;gap:var(--s3);
}
.tile .journal{
  font:600 var(--fs-xs)/1.3 var(--body);letter-spacing:.12em;text-transform:uppercase;
  color:var(--forest-2);
}
.tile h3{font-size:var(--fs-lg)}
.tile p{color:var(--ink-muted);font-size:var(--fs-md)}
/* Labels keep their natural height; only the body copy takes up the slack, so
   headings stay on one baseline across a row. */
.tile p:not(.journal):not(.n):not(.caveat){flex:1}
.n{font-size:var(--fs-sm);color:var(--forest-2);font-variant-numeric:tabular-nums}

/* ---------- pricing teaser ---------- */
/* Three cards, the same three the pricing page sells, spanning the content
   width like every other grid on Home. The old 820px cap left the block flush
   left with a third of the row empty, which read as a section out of line. */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s5);margin-top:var(--s7)}
@media (max-width:880px){ .plans{grid-template-columns:1fr} }
.plan{
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-card);padding:var(--s6);
}
.plan.featured{border-color:var(--ember);border-width:1.5px}
.plan .price{font-family:var(--display);font-size:var(--fs-3xl);font-weight:700;line-height:1;letter-spacing:-0.03em;font-variant-numeric:tabular-nums}
.plan .price .unit{font-family:var(--body);font-size:var(--fs-base);font-weight:400;letter-spacing:0;color:var(--ink-muted)}
.plan ul{list-style:none;margin:var(--s4) 0 0;padding:0;display:grid;gap:10px;font-size:var(--fs-md);color:var(--ink-muted)}
.plan li{display:flex;gap:10px;align-items:flex-start}
.plan li svg{width:16px;height:16px;color:var(--sage);flex:none;margin-top:4px}

/* ---------- footer ---------- */
footer{background:var(--forest);color:var(--on-forest);padding:var(--s8) 0 var(--s7)}
footer a{color:var(--on-forest-muted);text-decoration:none}
footer a:hover{color:var(--on-forest)}
.fgrid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:var(--s6)}
@media (max-width:760px){ .fgrid{grid-template-columns:1fr 1fr} }
footer h4{font:600 var(--fs-xs)/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--on-forest-muted);margin:0 0 var(--s4)}
footer ul{list-style:none;margin:0;padding:0;display:grid;gap:10px;font-size:var(--fs-md)}
footer .brand{color:var(--on-forest)}
/* .micro defaults to --ink-muted, which is near-invisible on forest. */
footer .micro{color:var(--on-forest-muted)}
/* The publisher mark, beside the copyright line it already carries. The
   supplied artwork is a blue gradient, which the brief bans, so the version
   served here is the same shapes flattened to the footer's own muted mint.
   Quiet by default: it says who publishes this, it is not a second brand
   competing with the product. */
.fpub{display:inline-flex;align-items:center;opacity:.7;transition:opacity .15s}
.fpub:hover{opacity:1}
.fpub img{height:44px;width:auto;display:block}
.fbase{
  margin-top:var(--s8);padding-top:var(--s5);border-top:1px solid var(--forest-line);
  display:flex;flex-wrap:wrap;gap:var(--s3) var(--s5);
  font-size:var(--fs-sm);color:var(--on-forest-muted);
}
.fbase .spacer{margin-left:auto}

/* ---------- interior page head ----------
   Interior pages open on type, not video, so h1 runs a step smaller than the
   home hero or it swallows the whole first screen. */
.page-head{padding:var(--s8) 0 var(--s7)}
.page-head h1{font-size:var(--fs-h1-page);max-width:19ch}
.page-head .lede{margin-top:var(--s5);font-size:var(--fs-lede-page);max-width:46ch}
.page-head .prose{margin-top:var(--s5)}
/* ---------- mint download button (pricing + account) ---------- */
.notify{
  display:inline-flex;align-items:center;gap:9px;white-space:nowrap;
  font:600 var(--fs-md)/1 var(--body);color:var(--forest);text-decoration:none;
  background:var(--mint);border-radius:var(--r-pill);padding:var(--s3) 20px;min-height:var(--tap);
  transition:background var(--t-base);
}
.notify:hover{background:color-mix(in srgb,var(--mint) 80%,var(--surface))}
.notify svg{width:16px;height:16px;flex:none}

/* ---------- legal pages (privacy, terms) ---------- */
.legal{padding-top:0}
.legal .prose h2{font-size:var(--fs-h3);color:var(--ink);margin:var(--s7) 0 var(--s3)}
.legal .prose h2:first-of-type{margin-top:0}
.legal .prose h3{font-size:var(--fs-base);font-weight:600;color:var(--ink);margin:var(--s5) 0 var(--s2)}
.legal .prose p,.legal .prose li{font-size:var(--fs-body);line-height:1.6}
.legal .prose p{margin:0 0 var(--s4)}
.legal .prose ul{margin:0 0 var(--s4);padding-left:var(--s5)}
.legal .prose li{margin-bottom:var(--s2)}
.legal .prose a{color:var(--forest);font-weight:500}
.legal .prose code{font-size:var(--fs-sm);background:var(--mint);border-radius:var(--r-xs);padding:1px 6px}
.legal .prose b{color:var(--ink)}
.legal .prose ol{margin:0 0 var(--s4);padding-left:var(--s5)}
/* Numbered contents list at the top of a policy. The ol supplies the numbers,
   so the link text carries none. */
/* ---------- legal pages: a centred document ----------
   The shape used on bortlebuddy.com/privacy-policy: one narrow column centred
   in the page, a centred title block carrying both dates, and the contents in
   a boxed two-column list. Body copy stays left aligned, which is what keeps a
   long policy readable; only the header and the contents box centre. */
.legal-head{text-align:center}
.legal-head .wrap,.legal .wrap{max-width:860px}
.legal-head h1{max-width:none;margin-inline:auto}
.legal-head .eyebrow{margin-bottom:var(--s3)}
.legal-dates{
  margin:var(--s5) 0 0;font-size:var(--fs-md);color:var(--ink-muted);
  padding-bottom:var(--s6);border-bottom:1px solid var(--line);
}
.legal-dates b{color:var(--ink);font-weight:600}
.legal-dates .d{display:inline-block;white-space:nowrap}
/* inherits --ink-muted: --sage on --ground is 3.35:1 and fails the contrast check */
.legal-dates .sep{padding:0 var(--s2)}
.legal .prose{max-width:none}
.legal .prose h2{padding-top:var(--s5);border-top:1px solid var(--line)}
.legal .prose h2:first-of-type,.legal .toc-box h2{padding-top:0;border-top:0}
.toc-box{background:var(--mint);border-radius:var(--r-card);padding:var(--s5) var(--s6);margin:0 0 var(--s7)}
.toc-box h2{font-size:var(--fs-base);margin:0 0 var(--s3)}
.legal .prose ol.toc{columns:2;column-gap:var(--s7);margin:0;padding-left:var(--s5)}
.legal .prose ol.toc li{margin-bottom:var(--s1)}
.legal .prose ol.toc a{font-weight:400}
/* Callout for a clause the reader must not miss, such as the arbitration
   agreement. Amber, because ember is reserved for actions. */
.legal .prose .notice{
  background:var(--wall);border-left:3px solid var(--amber);
  border-radius:0 var(--r-xs) var(--r-xs) 0;
  padding:var(--s4) var(--s5);margin:0 0 var(--s6);color:var(--ink);
}
@media (max-width:640px){
  .toc-box{padding:var(--s4) var(--s5)}
  .legal .prose ol.toc{columns:1}
}
.legal .prose .micro{color:var(--ink-muted)}
/* The lawyer's drafts carry tables: legal bases, providers, retention. They
   scroll on a phone rather than squeezing the text to nothing. */
.legal .tablewrap{overflow-x:auto;margin:0 0 var(--s5)}
.legal table{border-collapse:collapse;width:100%;min-width:440px;font-size:var(--fs-md)}
.legal th{
  text-align:left;font-weight:600;color:var(--ink);background:var(--wall);
  padding:var(--s3) var(--s4);border-bottom:1.5px solid var(--line);
}
.legal td{padding:var(--s3) var(--s4);border-bottom:1px solid var(--line);vertical-align:top;line-height:1.55}
.legal tr:last-child td{border-bottom:0}
.legal td:first-child{font-weight:500;color:var(--ink)}

/* ---------- research grid extras ----------
   The grid is five cards across six slots. The null-result card takes the two
   spare ones and inverts, because it is the card that earns the page its
   credibility and a uniform grid would bury it. See BRIEF.md §5. */
.tile-wide{grid-column:span 2}
.tile-dark{background:var(--forest);color:var(--on-forest)}
.tile-dark p{color:var(--on-forest-muted)}
.tile-dark .journal,.tile-dark .n{color:var(--on-forest-muted)}
.tile-dark .src{color:var(--on-forest-muted)}
.tile-dark .src:hover{color:var(--on-forest)}
.tile-wide h3{font-size:var(--fs-xl);max-width:22ch}
.tile .caveat{
  font-size:var(--fs-sm);color:var(--forest-2);border-top:1px solid var(--line);
  padding-top:var(--s3);margin-top:var(--s2);
}
.tile-dark .caveat{border-top-color:var(--forest-line);color:var(--on-forest-muted)}
@media (max-width:880px){ .tile-wide{grid-column:auto} }

/* ---------- two findings side by side ----------
   Used once, for the two Cochrane reviews that disagree. A rule between them
   rather than two cards, so it reads as one argument and not as a feature grid. */
.split{
  display:grid;grid-template-columns:1fr 1fr;gap:var(--s7);
  margin-top:var(--s8);padding-top:var(--s7);border-top:1px solid var(--line);
}
.split>div:first-child{padding-right:var(--s7);border-right:1px solid var(--line)}
.split h3{margin-bottom:var(--s3)}
.split .journal{
  font:600 var(--fs-xs)/1.3 var(--body);letter-spacing:.12em;text-transform:uppercase;
  color:var(--forest-2);margin-bottom:var(--s3);
}
.split p{color:var(--ink-muted);font-size:var(--fs-md)}
.split .figure{
  font-family:var(--display);font-weight:700;font-size:var(--fs-2xl);letter-spacing:-0.03em;
  line-height:1.1;margin:var(--s4) 0 var(--s2);
}
@media (max-width:880px){
  .split{grid-template-columns:1fr;gap:var(--s6)}
  .split>div:first-child{padding-right:0;border-right:0;border-bottom:1px solid var(--line);padding-bottom:var(--s6)}
}

/* ---------- limits list ----------
   Deliberately not a card grid. It is a list of concessions and it should read
   like one. */
.limits{list-style:none;margin:var(--s7) 0 0;padding:0;max-width:72ch;display:grid;gap:0}
.limits li{padding:var(--s5) 0;border-bottom:1px solid var(--line);display:grid;gap:var(--s2)}
.limits li:first-child{border-top:1px solid var(--line)}
.limits b{font-family:var(--display);font-size:var(--fs-lg);font-weight:600;letter-spacing:-0.015em}
.limits span{color:var(--ink-muted);font-size:var(--fs-md);max-width:62ch}

