/* ============================================================
   Soberya — WP theme layer
   Sits on top of tokens.css, which is a BYTE-IDENTICAL copy of the
   handoff's assets/css/soberya-web.css. Keep it that way: it is the
   design system shared with the iOS app, so a handoff update is a
   straight re-copy. Every WordPress-specific rule, fix and override
   belongs in THIS file. (skill: architecture.md)
   ============================================================ */

body{background:var(--sb-desk)}                          /* canvas outside the frame */
.sb-page{background:var(--sb-page);box-shadow:0 0 0 1px var(--sb-hairline)}
.is-disabled{opacity:.55;pointer-events:none}

/* Smooth scroll is opt-in only for people who did not ask to reduce motion. */
@media (prefers-reduced-motion:no-preference){ html{scroll-behavior:smooth} }

/* ---------- skip link: hidden until focused, then unmissable ---------- */
.sb-skip{
	position:absolute;left:-9999px;top:0;z-index:200;
	padding:12px 20px;border:2.5px solid var(--sb-ink);border-radius:0 0 var(--sb-r-md) 0;
	background:var(--sb-primary);color:#fff;font-weight:900;font-size:14px;text-decoration:none;
}
.sb-skip:focus{left:0}
[data-theme="dark"] .sb-skip{color:#241A33}
.sb-visually-hidden{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- header (sticky) ---------- */
.sb-header{position:sticky;top:0;z-index:50;max-width:var(--sb-max);margin:0 auto;background:var(--sb-surface)}
/* `.sb-nav a` (0,1,1) outranks `.sb-btn--primary` (0,1,0) and was painting the
   header CTA label in --sb-text-dim on --sb-primary (1.9:1). Match specificity. */
.sb-nav a.sb-btn--primary,.sb-mobile-menu a.sb-btn--primary{color:#fff}
[data-theme="dark"] .sb-nav a.sb-btn--primary,[data-theme="dark"] .sb-mobile-menu a.sb-btn--primary{color:#241A33}
.sb-nav a.sb-btn:hover,.sb-mobile-menu a.sb-btn:hover{text-decoration:none}
.sb-btn__icon{flex:none}

/* ---------- buttons the handoff CSS does not define ---------- */
.sb-store-row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
.sb-store-row--stacked{flex-direction:column;align-items:stretch;flex:none;width:262px}
.sb-store-row--stacked .sb-btn{width:100%}
/* The artboard's large buttons are chunkier than the 52px/2.5px the token doc
   lists — 54px in the 404, 58px in the CTA, 62px in the hero. One size, 56px,
   reads correctly against all three. */
.sb-btn--lg{height:56px;border-width:var(--sb-bw);border-radius:17px;box-shadow:var(--sb-shadow-lg)}
.sb-btn--lg:active{box-shadow:0 2px 0 var(--sb-ink)}
.sb-btn--outline{background:var(--sb-surface-2);color:var(--sb-heading)}
.sb-btn.is-soon{cursor:default}

/* ---------- mobile nav ---------- */
.sb-menu-toggle{display:none;font-size:17px;padding:0 14px}
.sb-mobile-menu{
	display:none;flex-direction:column;gap:14px;
	padding:18px var(--sb-gutter) 26px;background:var(--sb-surface);
	border-bottom:2.5px solid var(--sb-ink);
}
.sb-mobile-menu.is-open{display:flex}
.sb-mobile-menu a{font-weight:900;font-size:18px;color:var(--sb-heading)}
.sb-mobile-menu a:not(.sb-btn){padding:9px 14px;border-radius:var(--sb-r-sm);border:2.5px solid transparent}
.sb-mobile-menu a:not(.sb-btn)[aria-current="page"],
.sb-mobile-menu a:not(.sb-btn).is-active{
	color:var(--sb-heading);background:var(--sb-warm);
	border-color:var(--sb-ink);box-shadow:var(--sb-shadow-sm);
}
.sb-mobile-menu .sb-btn{align-self:flex-start}

/* ---------- footer language picker + theme switch ---------- */
/* The menu is `position:absolute; bottom:100%`, so its wrapper MUST establish a
   containing block or it lands against the viewport instead of the button. */
.sb-lang-wrap{position:relative;flex:none}
/* ---- Small in-article CTA -------------------------------------------
   Injected once into the post body as [sb_mini_cta]. Quiet enough to sit
   inside the reading flow, but alive: the same rising bubbles the home hero
   uses, two mascots, and both store badges. */
.sb-article__body .sb-minicta{
	position:relative;overflow:hidden;
	display:flex;align-items:center;gap:14px 16px;flex-wrap:wrap;
	margin:30px 0;padding:16px 20px;
	background:var(--sb-warm);border:2.5px solid var(--sb-ink);
	border-radius:var(--sb-r-lg);box-shadow:0 4px 0 var(--sb-ink);
}
/* Bubbles sit behind everything and never take pointer events. */
.sb-minicta__bubbles{position:absolute;inset:0;pointer-events:none;z-index:0}
.sb-minicta__bubbles .sb-bubble{bottom:-14px}
.sb-minicta__art{position:relative;z-index:1;flex:none;width:78px;height:62px;display:block}
.sb-minicta__mascot{position:absolute;left:0;bottom:0;animation:sb-bob 3.6s ease-in-out infinite}
.sb-minicta__mascot--b{left:auto;right:-4px;bottom:-2px;animation-delay:-1.8s}
.sb-minicta__text{
	position:relative;z-index:1;flex:1 1 190px;min-width:0;
	font-weight:900;font-size:15.5px;line-height:1.35;color:var(--sb-heading);
}

/* Store badges — shared by the small CTA and anywhere else two stores appear. */
.sb-storebar{position:relative;z-index:1;display:flex;gap:10px;flex-wrap:wrap;flex:none}
.sb-storebar__btn{
	display:inline-flex;align-items:center;gap:9px;
	padding:8px 14px;border-radius:12px;text-decoration:none;
	background:var(--sb-ink);color:#FFFFFF;border:2.5px solid var(--sb-ink);
}
.sb-storebar__btn:hover{background:#3E2E5C;color:#FFFFFF}
.sb-storebar__btn.is-soon{background:var(--sb-surface);color:var(--sb-heading);cursor:default}
.sb-storebar__icon{flex:none}
.sb-storebar__text{display:flex;flex-direction:column;line-height:1.15;text-align:left}
/* Both lines must stay on one line each. Without this the two-word kicker
   ("Coming soon on", "Sắp có trên") wraps and the badge collapses into a
   three-line block that clips its own text. */
.sb-storebar__text small,.sb-storebar__text b{white-space:nowrap}
.sb-storebar__text small{font-weight:800;font-size:9.5px;letter-spacing:.4px;text-transform:uppercase;opacity:.82}
.sb-storebar__text b{font-weight:900;font-size:14px}
.sb-storebar--sm .sb-storebar__btn{padding:7px 12px}
.sb-storebar--sm .sb-storebar__text b{font-size:13px}

@media (max-width:560px){
	.sb-article__body .sb-minicta{gap:12px}
	.sb-minicta__text{flex-basis:100%}
	.sb-storebar{width:100%}
	.sb-storebar__btn{flex:1 1 0;justify-content:center}
}
@media (prefers-reduced-motion:reduce){
	.sb-minicta__bubbles{display:none}
	.sb-minicta__mascot{animation:none}
}

/* ---- Blog app CTA ---------------------------------------------------
   Closes every article and the blog index. Structure follows the reference
   the client sent (eyebrow, headline, lead, stores, reassurances, art to one
   side); the surface is the theme's own — coral ground, 3px ink border, hard
   offset shadow, never blurred. */
.sb-appcta-section{padding-top:8px;padding-bottom:56px}
.sb-appcta{
	position:relative;display:flex;align-items:center;gap:34px;
	padding:38px 40px;border-radius:var(--sb-r-xl);
	background:var(--sb-primary);color:#FFFFFF;
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:0 8px 0 var(--sb-ink);
	overflow:hidden;
}
.sb-appcta__copy{flex:1 1 auto;min-width:0;position:relative;z-index:1}
.sb-appcta__eyebrow{
	margin:0 0 10px;font-weight:900;font-size:12px;letter-spacing:1.1px;
	text-transform:uppercase;color:rgba(255,255,255,.86);
}
.sb-appcta__title{margin:0;color:#FFFFFF;text-wrap:balance}
.sb-appcta__sub{
	margin:12px 0 0;max-width:46ch;font-size:16px;line-height:1.65;
	color:rgba(255,255,255,.94);
}
.sb-appcta__actions{margin-top:22px}
/* The card is coral in BOTH themes, so the buttons on it cannot use tokens that
   flip with the theme: --sb-surface and --sb-heading both resolve dark in dark
   mode, which painted the App Store button ink-on-ink at a contrast of 1.0 —
   a solid black box with invisible text. Fixed values, 13.7:1 either way. */
.sb-appcta .sb-btn--primary,
.sb-appcta .sb-btn--primary span,
.sb-appcta .sb-btn--primary svg{background:none;color:#241A33}
.sb-appcta .sb-btn--primary{background:#FFF9F0;border-color:#241A33}
.sb-appcta .sb-btn--primary:hover{background:#FFFFFF}
.sb-appcta .sb-btn--outline,
.sb-appcta .sb-btn--outline span{background:transparent;color:#FFFFFF}
.sb-appcta .sb-btn--outline{border-color:#FFFFFF}
.sb-appcta .sb-btn--outline:hover{background:rgba(255,255,255,.14)}

.sb-appcta__ticks{
	list-style:none;margin:20px 0 0;padding:0;
	display:flex;flex-wrap:wrap;gap:8px 26px;
}
.sb-appcta__ticks li{
	display:flex;align-items:center;gap:8px;
	font-weight:800;font-size:14.5px;color:rgba(255,255,255,.94);
}
.sb-appcta__tick{flex:none;color:#FFFFFF}

.sb-appcta__art{
	position:relative;flex:none;width:230px;height:200px;
	display:grid;place-items:center;
}
.sb-appcta__ring{
	position:absolute;width:186px;height:186px;border-radius:50%;
	background:rgba(255,255,255,.16);border:2.5px solid rgba(255,255,255,.42);
}
.sb-appcta__mascot{position:relative;z-index:1}
.sb-appcta__mascot--small{position:absolute;right:2px;bottom:6px;z-index:2}

@media (max-width:860px){
	.sb-appcta{flex-direction:column;align-items:flex-start;gap:24px;padding:30px 26px}
	.sb-appcta__sub{max-width:none}
	.sb-appcta__art{width:100%;height:170px}
	.sb-appcta__mascot--small{right:auto;left:56%}
}
@media (max-width:520px){
	.sb-appcta__ticks{flex-direction:column;gap:9px}
}

/* ---- Language picker -------------------------------------------------
   tokens.css sizes this menu for the 6 languages the mock had. We now ship
   14, so a single 190px column would be a tall thin strip that opens off the
   top of the viewport. Two columns, wider, with a flag per row. */
.sb-lang__menu{
	min-width:0;
	width:min(384px,calc(100vw - 32px));
	max-height:min(60vh,420px);overflow-y:auto;
	padding:8px;
}
.sb-lang__grid{
	display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px;
}
.sb-lang__item{
	justify-content:flex-start;gap:9px;padding:8px 10px;
}
/* Emoji flags come from the system emoji font; the text stack has no glyph
   for them, so name it explicitly or Linux/Windows render tofu boxes. */
.sb-lang__flag{
	font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif;
	font-size:16px;line-height:1;flex:none;
}
.sb-lang__name{
	flex:1 1 auto;min-width:0;
	overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sb-lang__check{flex:none;width:9px;text-align:right}
/* tokens.css paints the selected row white-on-(--sb-primary) = 2.64:1, below
   the 4.5:1 AA floor — and this is the one row a user most needs to read.
   Not --sb-primary-ink: that token flips lighter in dark mode because its job
   there is TEXT on a dark ground. Here it would be a BACKGROUND under fixed
   white text, inside a footer that is dark in both themes, so it has to be one
   constant value. Same coral hue, 5.39:1 on white. */
.sb-lang__item[aria-selected="true"],
.sb-lang__item[aria-selected="true"]:hover{background:var(--sb-on-primary);color:#FFFFFF}
.sb-lang__item[aria-selected="true"]:hover{filter:brightness(1.1)}
.sb-lang__caret{margin-left:2px;font-size:11px}
.sb-lang-wrap:has([aria-expanded="true"]) .sb-lang__caret{transform:rotate(180deg)}
.sb-lang__caret{display:inline-block;transition:transform .15s ease}
@media (prefers-reduced-motion:reduce){.sb-lang__caret{transition:none}}

/* One column below 420px: two 160px columns start truncating endonyms. */
@media (max-width:420px){
	.sb-lang__grid{grid-template-columns:1fr}
	.sb-lang__menu{width:min(260px,calc(100vw - 32px))}
}
/* The footer picker sits at the left edge, but the menu is now wide enough
   to run off-screen on narrow phones when the wrap is not at x=0. */
@media (max-width:600px){
	.sb-lang__menu{left:50%;transform:translateX(-50%)}
}

.sb-lang__note{
	margin:8px 6px 4px;padding-top:8px;border-top:2px solid var(--sb-footer-line);
	font-weight:700;font-size:11.5px;line-height:1.45;color:var(--sb-footer-dim);
}

.sb-footer__bottom-left{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.sb-footer__col-title{margin:0 0 6px;font-weight:900;font-size:11.5px;letter-spacing:1px;text-transform:uppercase;color:var(--sb-footer-dim)}
.sb-footer__note{margin:0;font-weight:700;font-size:13px;color:var(--sb-footer-dim)}
.sb-footer__prefs{background:none;border:0;padding:3px 0;font:800 13.5px var(--sb-font-body);color:var(--sb-footer-text);cursor:pointer;text-align:left}
.sb-footer__prefs:hover{text-decoration:underline}

/* ---------- hero ---------- */
.sb-hero{position:relative;overflow:hidden}
.sb-hero__grid{display:grid;grid-template-columns:1.1fr .9fr;gap:40px;align-items:center}
.sb-hero__badge{display:inline-flex;align-items:center;gap:8px;font-weight:900;font-size:12px;letter-spacing:1px;text-transform:uppercase}
.sb-hero__phone{position:relative;display:grid;place-items:center;min-height:660px}
/* The artboard draws these as real Pop Kẹo bubbles: a solid 2px ink outline,
   not a faint translucent hairline. */
.sb-bubble{position:absolute;bottom:-40px;border-radius:50%;background:var(--sb-surface-2);border:2px solid var(--sb-ink);animation:sb-bubble 9s linear infinite;pointer-events:none;z-index:0}
/* Far enough to clear the whole hero, so they drift PAST the phone rather than
   bobbing about beneath it. */
.sb-hero .sb-bubble{--sb-rise:-860px}
[data-theme="dark"] .sb-bubble{background:var(--sb-surface-2)}
/* Ink ring behind the phone (336px in the artboard). */
.sb-hero__shot{position:relative;z-index:1}
/* The floating feature chips. z-index 4 puts them over the phone on purpose —
   they read as cards lifted off the screen. Their VALUES must agree with the
   capture behind them: the pair used to say "$248 saved this month" over a
   screen showing $312, which is the kind of detail a careful reader catches. */
.sb-hero__chip{position:absolute;background:var(--sb-surface-2);border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);border-radius:13px;padding:7px 12px;font-weight:900;font-size:12px;color:var(--sb-heading);white-space:nowrap;z-index:4;line-height:1.3}
.sb-hero__chip small{display:block;font-size:9.5px;letter-spacing:.6px;text-transform:uppercase;color:var(--sb-text-faint)}
.sb-hero__chip b{font-family:var(--sb-font-display);font-size:15px;color:var(--sb-primary-ink)}
/* Anchored to the PHONE, not to the column. The phone is centred in a wider
   column, so plain left/right offsets put the chips on top of the screen and
   hid the milestone bar.
   One rule instead of three tuned numbers: every chip crosses the phone's edge
   by --sb-chip-over, and the edge itself is derived from the phone's own width
   so re-sizing the phone cannot silently move them onto the screen.
   margin-*, not transform — sb-bob owns the transform. */
.sb-hero__phone{
	--sb-chip-edge:calc((288px + 10px) / 2);   /* .sb-phone--lg + its 5px frame */
	--sb-chip-over:34px;
}
.sb-hero__chip--1,
.sb-hero__chip--3{right:50%;margin-right:calc(var(--sb-chip-edge) - var(--sb-chip-over))}
.sb-hero__chip--2{left:50%;margin-left:calc(var(--sb-chip-edge) - var(--sb-chip-over))}
/* Vertically they sit in the screen's quiet bands, clear of the greeting, the
   milestone bar and the two stat tiles. */
.sb-hero__chip--1{top:44px;animation:sb-bob 4.2s ease-in-out infinite}
.sb-hero__chip--2{top:292px;animation:sb-bob 3.4s ease-in-out infinite}
.sb-hero__chip--3{bottom:74px;animation:sb-bob 4.8s ease-in-out infinite}
@media (max-width:900px){
	/* A narrow column has no room outside the phone, so they lie further over it. */
	.sb-hero__phone{--sb-chip-over:96px}
}
.sb-hero__ring{
	position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
	width:336px;height:336px;border-radius:50%;
	border:var(--sb-bw) solid var(--sb-ink);pointer-events:none;z-index:0;
}
.sb-twinkle{position:absolute;color:var(--sb-accent);font-size:13px;animation:sb-twinkle 2.8s ease-in-out infinite;pointer-events:none;z-index:0;display:none}
[data-theme="dark"] .sb-twinkle{display:block}

/* ---------- social proof band ---------- */
.sb-proof{background:#33254A;color:rgba(255,242,227,.72);text-align:center}
.sb-proof__title{font-family:var(--sb-font-display);font-size:13px;letter-spacing:2px;text-transform:uppercase;margin:0 0 14px}
.sb-proof__row{display:flex;flex-wrap:wrap;justify-content:center;gap:14px 40px;align-items:center}
.sb-proof__row span{font-family:var(--sb-font-display);font-size:17px;opacity:.72}

/* ---------- value cards ---------- */
.sb-value__icon{display:grid;place-items:center;width:60px;height:60px;border-radius:20px;border:2.5px solid var(--sb-ink);font-size:28px}
.sb-head-wrap{max-width:680px}
.sb-head-wrap.center{margin:0 auto;text-align:center}
.sb-eyebrow--warm{color:var(--sb-warm-ink)}

/* ---------- mascot yard ---------- */
/* The band is delimited top and bottom by the same 3px ink rule the artboard
   uses, and the ground runs edge to edge — it breaks out of the section gutter. */
.sb-yard-section{
	background:var(--sb-warm);
	border-top:var(--sb-bw) solid var(--sb-ink);
	border-bottom:var(--sb-bw) solid var(--sb-ink);
	padding-bottom:0;
}
/* The CTA drops to the bottom of the copy block so it lands just above the
   "live animation" caption, instead of floating up beside the eyebrow. */
.sb-yard__head{display:flex;align-items:flex-end;justify-content:space-between;gap:30px}
.sb-yard__cta{flex:none;margin-bottom:2px}
.sb-yard__caption{margin:14px 0 6px;text-align:right;font-weight:800;font-size:11.5px;color:var(--sb-warm-text)}
.sb-yard{margin-left:calc(var(--sb-gutter) * -1);margin-right:calc(var(--sb-gutter) * -1)}
.sb-yard__grass{position:absolute;bottom:38px;font-size:19px;transform-origin:50% 100%;animation:sb-grass 3.2s ease-in-out infinite}
.sb-runner{position:absolute;left:-170px;bottom:34px;animation:sb-run 9s linear infinite}
.sb-runner__body{position:relative;animation:sb-step .44s ease-in-out infinite}
.sb-runner__dust{position:absolute;left:-22px;top:78px;font-size:17px;animation:sb-dust .6s linear infinite}
.sb-runner__say{
	position:absolute;left:104px;top:6px;white-space:nowrap;
	background:var(--sb-surface);border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);
	border-radius:13px;padding:3px 10px;
	font-family:var(--sb-font-display);font-size:13px;color:var(--sb-primary-ink);
}
/* The label sits below the 140px art; the band clips overflow, so reserve room. */
.sb-mascot__label{color:var(--sb-warm-text)}

/* ---------- stats + calendar ---------- */
.sb-stats__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.sb-cal-copy .sb-stats__num{font-size:30px}
.sb-cal-copy .sb-stats__lbl{font-size:13px;margin-top:4px}
.sb-stats__num{font-family:var(--sb-font-display);font-size:46px;line-height:1;color:var(--sb-heading)}
.sb-stats__num--accent{color:var(--sb-primary)}
.sb-stats__lbl{font-weight:900;font-size:13.5px;color:var(--sb-text-dim);margin-top:8px}
/* Calendar card left at a fixed 440px, copy right — the artboard layout. */
.sb-cal-row{display:flex;gap:40px;align-items:center}
.sb-cal-copy{flex:1;min-width:0}
.sb-cal{
	flex:none;width:440px;
	background:var(--sb-surface);border:var(--sb-bw) solid var(--sb-ink);
	box-shadow:var(--sb-shadow-lg);border-radius:var(--sb-r-xl);padding:24px;
}
.sb-cal__head{display:flex;justify-content:space-between;align-items:center;gap:12px}
.sb-cal__month{font-family:var(--sb-font-display);font-size:19px;color:var(--sb-heading)}
.sb-cal__grid{display:grid;grid-template-columns:repeat(7,1fr);gap:7px;margin-top:16px}
.sb-cal__dow{font-weight:900;font-size:10px;color:var(--sb-text-faint);text-align:center;text-transform:uppercase}
/* Every square carries its date, so the colour is a second channel, not the only one. */
.sb-cal__day{
	aspect-ratio:1;border-radius:10px;background:var(--sb-hairline);
	display:grid;place-items:center;
	font-weight:900;font-size:13px;color:var(--sb-heading);
}
.sb-cal__day--pad{background:none}
.sb-cal__day[data-l="clean"]{background:var(--sb-success)}
.sb-cal__day[data-l="under"]{background:var(--sb-accent)}
.sb-cal__day[data-l="over"]{background:#FF8A63}
[data-theme="dark"] .sb-cal__day[data-l="clean"],
[data-theme="dark"] .sb-cal__day[data-l="under"],
[data-theme="dark"] .sb-cal__day[data-l="over"]{color:#140B22}
/* Days after today are not logged yet — a sample must not invent the future. */
.sb-cal__day--future{background:none;color:var(--sb-text-faint)}
.sb-cal__day--today{background:none;color:var(--sb-primary-ink);box-shadow:inset 0 0 0 2px var(--sb-primary)}
.sb-cal__legend{display:flex;flex-wrap:wrap;gap:8px 14px;margin:14px 0 0;padding:0;list-style:none}
.sb-cal__legend li{display:flex;align-items:center;gap:6px;font-weight:800;font-size:11.5px;color:var(--sb-text-dim)}
.sb-cal__legend i{width:11px;height:11px;border-radius:4px;background:var(--sb-hairline);flex:none}
.sb-cal__legend i[data-l="clean"]{background:var(--sb-success)}
.sb-cal__legend i[data-l="under"]{background:var(--sb-accent)}
.sb-cal__legend i[data-l="over"]{background:#FF8A63}
.sb-cal__note{margin:16px 0 0;font-weight:800;font-size:11.5px;color:var(--sb-text-faint)}
.sb-stats__num--1{color:var(--sb-primary-ink)}
.sb-stats__num--2{color:var(--sb-success-ink)}
.sb-stats__num--3{color:var(--sb-warm-ink)}

/* ---------- final CTA ---------- */
.sb-cta{
	background:var(--sb-primary);color:var(--sb-ink);
	border:var(--sb-bw) solid var(--sb-ink);     /* the artboard outlines the band */
	border-radius:var(--sb-r-2xl);box-shadow:var(--sb-shadow-xl);
	padding:52px;display:flex;align-items:center;justify-content:space-between;gap:40px;
}
[data-theme="dark"] .sb-cta{color:#241A33}
.sb-cta__copy{min-width:0}
.sb-cta .sb-h2{color:inherit}
/* The artboard's #FFE0DC on the red band is 2.37:1 — use the ink the rest of
   the band already uses (4.74:1) and let opacity carry the "secondary" role. */
.sb-cta__sub{margin:12px 0 0;font-weight:800;font-size:16px;color:var(--sb-ink);opacity:.82}
[data-theme="dark"] .sb-cta__sub{color:#241A33}
.sb-cta__actions{flex:none}
/* Inside the red band a --sb-primary button would be invisible, so the artboard
   flips it to the cream surface and gives the secondary the dark ink fill. */
.sb-cta .sb-btn--primary{background:var(--sb-surface);color:var(--sb-heading)}
.sb-cta .sb-btn--outline{background:var(--sb-ink);color:var(--sb-footer-text);box-shadow:0 6px 0 var(--sb-primary-ink)}
.sb-cta .sb-btn--outline:active{box-shadow:0 2px 0 var(--sb-primary-ink)}
[data-theme="dark"] .sb-cta .sb-btn--primary{color:var(--sb-heading)}
.sb-cta .sb-btn{white-space:nowrap}

/* ---------- features page (artboard "Web Features") ---------- */
.sb-fhero{text-align:center;padding-bottom:40px}
.sb-fhero__title{font-size:clamp(34px,5vw,52px);line-height:1.08;margin-top:12px}
.sb-fhero__lead{margin:16px auto 0;max-width:620px}
.sb-fgrid-section{padding-top:20px}

.sb-fcard{
	position:relative;background:var(--sb-surface);
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	border-radius:22px;padding:24px;
}
.sb-fcard__icon{display:grid;place-items:center;width:54px;height:54px;border-radius:18px;border:2.5px solid var(--sb-ink);font-size:25px}
.sb-fcard__icon--rose{background:#FFEDE7}
.sb-fcard__icon--warm{background:var(--sb-warm)}
.sb-fcard__icon--mint{background:var(--sb-mint)}
.sb-fcard__icon--lilac{background:var(--sb-lilac)}
[data-theme="dark"] .sb-fcard__icon--rose{background:var(--sb-surface-2)}
.sb-fcard__title{font-size:21px;margin-top:14px}
.sb-fcard__body{margin-top:7px}
.sb-fcard__plus{
	position:absolute;top:18px;right:18px;
	background:var(--sb-purple-ink);color:#fff;border:2px solid var(--sb-ink);
	border-radius:9px;padding:3px 9px;
	font-weight:900;font-size:10.5px;letter-spacing:1px;text-transform:uppercase;
}
.sb-unlock{display:block;margin-top:22px}

/* two-column bands (widgets, privacy) */
.sb-band{background:var(--sb-surface);border-top:var(--sb-bw) solid var(--sb-ink);border-bottom:var(--sb-bw) solid var(--sb-ink)}
.sb-band--plain{background:var(--sb-page);border:0}
.sb-band__grid{display:flex;gap:48px;align-items:center}
.sb-band__grid--reverse .sb-band__copy{order:2}
.sb-band__copy{flex:1;min-width:0}
.sb-band__title{font-size:clamp(26px,3.4vw,36px);line-height:1.14;margin-top:10px}
.sb-sizes,.sb-trust{display:flex;flex-wrap:wrap;gap:10px;margin:20px 0 0;padding:0;list-style:none}
.sb-sizes li{background:var(--sb-warm);border:2px solid var(--sb-ink);border-radius:11px;padding:6px 12px;font-weight:900;font-size:12.5px;color:var(--sb-heading)}
.sb-trust li{background:var(--sb-mint);border:2.5px solid var(--sb-success);border-radius:12px;padding:8px 14px;font-weight:900;font-size:13px;color:var(--sb-success-ink)}

/* widget previews */
.sb-widgets{flex:none;display:flex;gap:16px;align-items:flex-start}
.sb-widget{
	background:var(--sb-page);border:var(--sb-bw) solid var(--sb-ink);
	box-shadow:0 5px 0 var(--sb-ink);border-radius:30px;
	display:flex;flex-direction:column;justify-content:space-between;
}
.sb-widget--sm{width:150px;height:150px;padding:14px}
.sb-widget--lg{width:322px;height:150px;padding:14px 16px}
.sb-widget__label{margin:0;font-weight:900;font-size:8px;letter-spacing:1.4px;text-transform:uppercase;color:var(--sb-text-faint)}
.sb-widget__streak{display:flex;align-items:flex-end;gap:8px}
.sb-widget__seed{width:42px;height:42px;flex:none;border-radius:50%;background:var(--sb-mint);border:2.5px solid var(--sb-ink);display:grid;place-items:center;font-size:21px;animation:sb-bob 3.4s ease-in-out infinite}
.sb-widget__streak b{display:block;font-family:var(--sb-font-display);font-size:30px;line-height:1;color:var(--sb-heading);font-weight:400}
.sb-widget__streak small{display:block;font-weight:800;font-size:9px;color:var(--sb-text-dim)}
.sb-widget__flame{font-size:15px;transform-origin:50% 85%;animation:sb-flick 1.6s ease-in-out infinite}
@keyframes sb-flick{0%,100%{transform:rotate(-4deg) scale(1)}35%{transform:rotate(4deg) scale(1.1)}65%{transform:rotate(-2deg) scale(.95)}}
.sb-widget__head{display:flex;justify-content:space-between;align-items:center;gap:8px}
.sb-widget__name{font-family:var(--sb-font-display);font-size:14px;color:var(--sb-heading)}
.sb-widget__keys{display:grid;grid-template-columns:1.25fr 1fr 1fr 1fr;gap:8px}
.sb-key{
	height:52px;border-radius:15px;background:var(--sb-surface-2);
	border:2.5px solid var(--sb-ink);box-shadow:0 4px 0 var(--sb-ink);
	display:flex;flex-direction:column;align-items:center;justify-content:center;
	font-weight:900;font-size:9.5px;color:var(--sb-heading);text-align:center;line-height:1.2;
}
.sb-key span{font-size:16px}
.sb-key--go{background:var(--sb-success);color:var(--sb-ink)}
.sb-key--alt{background:var(--sb-warm)}
.sb-widget__foot{margin:0;font-weight:800;font-size:9px;color:var(--sb-text-faint)}

/* privacy visibility card */
.sb-visicard{
	flex:none;width:420px;background:var(--sb-surface);
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	border-radius:var(--sb-r-xl);padding:22px;
}
.sb-visicard__title{font-size:18px}
.sb-visicard__rows{display:flex;flex-direction:column;gap:9px;margin-top:14px}
.sb-visirow{display:flex;align-items:center;gap:11px;background:var(--sb-surface-2);border:2px solid var(--sb-hairline);border-radius:14px;padding:10px 12px}
.sb-visirow--locked{background:var(--sb-warm);border-color:var(--sb-warm-border)}
.sb-visirow__icon{font-size:16px;flex:none}
.sb-visirow__label{flex:1;font-weight:900;font-size:13.5px;color:var(--sb-heading)}
.sb-visirow__always{font-weight:800;font-size:11px;color:var(--sb-warm-ink)}
.sb-switch{position:relative;width:40px;height:23px;flex:none;border-radius:13px;background:var(--sb-hairline);border:2px solid var(--sb-ink);display:inline-block}
.sb-switch.is-on{background:var(--sb-success)}
.sb-switch i{position:absolute;left:2px;top:1.5px;width:16px;height:16px;border-radius:50%;background:#fff;border:1.5px solid var(--sb-ink)}
.sb-switch.is-on i{left:auto;right:2px}

/* pricing row of three */
.sb-price{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:0}
.sb-price__card{display:flex;flex-direction:column;padding:28px}
/* On the lilac card the page's body/dim greys drop to 4.4 and 3.8:1 — the
   palette already has a lilac-safe ink, so use it. */
.sb-price__card--plus{background:var(--sb-lilac);color:var(--sb-lilac-ink)}
.sb-price__card--plus .sb-price__list li,
.sb-price__card--plus .sb-price__amount small{color:var(--sb-lilac-ink)}
.sb-price__card--help{background:var(--sb-ink);border-color:var(--sb-ink);box-shadow:0 6px 0 var(--sb-purple-ink)}
.sb-price__card--help .sb-h3{color:var(--sb-footer-text)}
.sb-price__helptext{color:#B9A6C4;margin-top:12px}  /* 6.19:1 on --sb-ink */
.sb-price__cta{margin-top:auto;width:100%;justify-content:center}
.sb-price__list + .sb-price__cta{margin-top:22px}
.sb-price__cta--plus{background:var(--sb-purple-ink);color:#fff}
.sb-price__cta--help{background:var(--sb-footer-text);color:var(--sb-ink);border-color:var(--sb-footer-text);box-shadow:none}
.sb-mascot-card{text-align:center;padding:20px}
.sb-mascot-card__shot{height:150px;border-radius:18px;background:var(--sb-page);border:2.5px solid var(--sb-hairline);display:grid;place-items:center;overflow:hidden;margin-bottom:14px}
.sb-mascot-card__drink{font-weight:900;font-size:11px;letter-spacing:1.4px;text-transform:uppercase;color:var(--sb-text-faint);margin:6px 0 0}
.sb-price__card{position:relative}
.sb-price__badge{position:absolute;top:-13px;right:20px;background:var(--sb-purple);color:#fff;border:2px solid var(--sb-ink);border-radius:var(--sb-r-sm);padding:3px 11px;font-weight:900;font-size:11px;letter-spacing:1px;text-transform:uppercase}
.sb-price__amount{font-family:var(--sb-font-display);font-size:38px;line-height:1.1;color:var(--sb-heading);margin:6px 0 0}
.sb-price__amount small{font-family:var(--sb-font-body);font-weight:800;font-size:14px;color:var(--sb-text-dim)}
.sb-price__list{list-style:none;margin:16px 0 0;padding:0;display:flex;flex-direction:column;gap:9px}
.sb-price__list li{display:flex;gap:9px;align-items:flex-start;font-size:14.5px;line-height:1.5}
.sb-price__list li::before{content:"✓";color:var(--sb-success-ink);font-weight:900;flex:none}
.sb-faq{display:flex;flex-direction:column;gap:14px;margin-top:26px}
.sb-faq details{background:var(--sb-surface);border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-md);border-radius:var(--sb-r-lg);padding:16px 20px}
.sb-faq summary{font-family:var(--sb-font-display);font-size:17px;color:var(--sb-heading);cursor:pointer;list-style:none}
.sb-faq summary::-webkit-details-marker{display:none}
.sb-faq summary::after{content:"+";float:right;font-size:20px;line-height:1;color:var(--sb-primary)}
.sb-faq details[open] summary::after{content:"–"}
.sb-faq p{margin:10px 0 0;font-size:15px}

/* ---------- comparison table + mood grid ---------- */
.sb-table-wrap{overflow-x:auto;border:var(--sb-bw) solid var(--sb-ink);border-radius:var(--sb-r-xl);box-shadow:var(--sb-shadow-lg);background:var(--sb-surface)}
.sb-table{width:100%;border-collapse:collapse;min-width:520px}
.sb-table th,.sb-table td{padding:13px 18px;text-align:left;border-bottom:2px solid var(--sb-hairline);font-size:14.5px}
.sb-table thead th{font-family:var(--sb-font-display);font-weight:400;font-size:16px;color:var(--sb-heading);background:var(--sb-warm);border-bottom:2.5px solid var(--sb-ink)}
.sb-table tbody th{font-weight:800;color:var(--sb-heading)}
.sb-table td{text-align:center;width:22%}
.sb-table tbody tr:last-child th,.sb-table tbody tr:last-child td{border-bottom:0}
.sb-yes{color:var(--sb-success-ink);font-weight:900;font-size:17px}
.sb-no{color:var(--sb-text-faint);font-weight:900}
.sb-moods{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:26px}
.sb-mood{
	margin:0;text-align:center;background:var(--sb-surface);
	border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-md);
	border-radius:var(--sb-r-lg);padding:14px 10px;
}
/* Reserve the bubble's row so a tile never resizes as its bubble pops. */
.sb-mood__stage{position:relative;padding-top:42px}
.sb-mood__art{display:block;animation:sb-bob 3.4s ease-in-out infinite}
.sb-mood__art img{margin:0 auto}
.sb-mood__say{
	position:absolute;top:0;left:-6px;right:-6px;margin:0 auto;width:max-content;max-width:100%;
	background:var(--sb-surface-2);border:2px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);
	border-radius:var(--sb-r-md);padding:5px 11px;
	font-weight:900;font-size:11.5px;line-height:1.3;color:var(--sb-heading);
	transform-origin:50% 100%;opacity:0;
	animation:sb-say-solo var(--cyc,6s) ease-in-out infinite;
}
/* Visible for most of the cycle — a single bubble that hides two-thirds of the
   time (like the four-way sb-say) would read as broken. */
@keyframes sb-say-solo{
	0%{opacity:0;transform:scale(.6)}
	7%{opacity:1;transform:scale(1.1)}
	12%{transform:scale(1)}
	78%{opacity:1;transform:scale(1)}
	86%{opacity:0;transform:scale(.85)}
	100%{opacity:0;transform:scale(.6)}
}
.sb-mood figcaption{margin-top:10px;font-weight:900;font-size:12px;color:var(--sb-text-dim)}
@media (max-width:900px){ .sb-moods{grid-template-columns:repeat(2,1fr)} }
@media (prefers-reduced-motion:reduce){
	/* Keep the words — they carry the meaning; just stop the motion. */
	.sb-mood__say{opacity:1;animation:none}
	.sb-mood__art{animation:none}
}

/* ---------- blog (artboard "Web Blog") ---------- */
.sb-bloghead{padding-bottom:26px}
.sb-bloghead__row{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap}
/* Cap the headline so the search pill stays on the same row, as in the
   artboard, instead of being pushed under a full-width title. */
.sb-bloghead__title{font-size:clamp(32px,4.6vw,48px);line-height:1.08;margin-top:10px;max-width:15ch}
.sb-chips-section{padding-top:8px;padding-bottom:30px}
.sb-postlist{padding-top:0}

.sb-searchform{
	display:flex;align-items:center;gap:10px;height:48px;width:280px;max-width:100%;
	padding:0 18px;border-radius:16px;background:var(--sb-surface);
	border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-md);
}
.sb-searchform__icon{flex:none;font-size:14px}
.sb-searchform input[type=search]{
	flex:1;min-width:0;height:100%;border:0;background:none;
	font:800 14px var(--sb-font-body);color:var(--sb-heading);
}
.sb-searchform input[type=search]::placeholder{color:var(--sb-text-faint)}
.sb-searchform input[type=search]:focus{outline:none}
.sb-searchform:focus-within{outline:3px solid var(--sb-purple);outline-offset:3px}

/* topic chips */
.sb-catchips{display:flex;flex-wrap:wrap;gap:10px}
.sb-catchip{
	border:2px solid var(--sb-hairline);border-radius:12px;padding:8px 15px;
	background:var(--sb-surface);font-weight:800;font-size:13px;color:var(--sb-heading);
	text-decoration:none;transition:transform .06s,box-shadow .06s;
}
.sb-catchip:hover{text-decoration:none;border-color:var(--sb-ink)}
.sb-catchip.is-on{
	background:var(--sb-primary);color:var(--sb-ink);font-weight:900;
	border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);
}
.sb-catchip:active{transform:translateY(3px);box-shadow:none}

/* featured band */

/* post cards */
.sb-postcard{background:var(--sb-surface);border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);border-radius:22px;overflow:hidden;padding:0;display:flex;flex-direction:column}
.sb-postcard__cover{height:150px;border-bottom:var(--sb-bw) solid var(--sb-ink);display:grid;place-items:center;overflow:hidden}
.sb-postcard__cover img{width:100%;height:100%;object-fit:cover}
.sb-postcard__cover--mint{background:var(--sb-mint)}
.sb-postcard__cover--warm{background:var(--sb-warm)}
.sb-postcard__cover--lilac{background:var(--sb-lilac)}
.sb-postcard__cover--rose{background:#FFEDE7}
[data-theme="dark"] .sb-postcard__cover--rose,
.sb-postcard__body{padding:20px}
.sb-postcard__cat{margin:0;font-weight:900;font-size:11.5px;letter-spacing:.6px;text-transform:uppercase}
.sb-postcard__cat--mint{color:var(--sb-success-ink)}
.sb-postcard__cat--warm{color:var(--sb-warm-ink)}
.sb-postcard__cat--lilac{color:var(--sb-purple-text)}
.sb-postcard__cat--rose{color:var(--sb-primary-ink)}
.sb-postcard__title{font-family:var(--sb-font-display);font-weight:400;font-size:19px;line-height:1.25;margin:8px 0 0}
.sb-postcard__title a{color:var(--sb-heading);text-decoration:none}
.sb-postcard__title a:hover{color:var(--sb-primary-ink);text-decoration:none}
.sb-postcard__excerpt{margin:8px 0 0;font-weight:700;font-size:13.5px;line-height:1.65;color:var(--sb-text)}
.sb-postcard__meta{margin:14px 0 0;font-weight:800;font-size:12px;color:var(--sb-text-faint)}
.sb-grid-posts{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}

/* newsletter */
.sb-news-section{padding-top:0}
.sb-news{
	background:#FFE1B8;border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	border-radius:26px;padding:38px 40px;
	display:flex;align-items:center;justify-content:space-between;gap:36px;flex-wrap:wrap;
}
[data-theme="dark"] .sb-news{background:var(--sb-surface-2)}
.sb-news__copy{min-width:0}
.sb-news__title{font-size:clamp(22px,2.6vw,28px);line-height:1.15}
.sb-news__sub{margin:8px 0 0;font-weight:700;font-size:15px;color:#6B5433}
[data-theme="dark"] .sb-news__sub{color:var(--sb-text)}
.sb-news__form{display:flex;gap:11px;flex:none;margin:0;flex-wrap:wrap}
.sb-news__form input[type=email]{
	width:290px;max-width:100%;height:56px;padding:0 16px;
	border:var(--sb-bw) solid var(--sb-ink);border-radius:16px;background:var(--sb-surface);
	font:800 14.5px var(--sb-font-body);color:var(--sb-heading);
}
.sb-news__form input[type=email]::placeholder{color:var(--sb-text-faint)}

/* ---------- single post (artboard "Web Single post") ---------- */
.sb-article-wrap{display:flex;gap:44px;align-items:flex-start;padding-bottom:0}
.sb-article{max-width:700px;flex:1;min-width:0;margin:0}
.sb-article__title{
	font-family:var(--sb-font-display);font-weight:400;
	font-size:clamp(30px,4.2vw,46px);line-height:1.1;margin:14px 0 0;
	color:var(--sb-heading);text-wrap:balance;
}

/* sticky contents card */
.sb-toc{flex:none;width:200px;position:sticky;top:96px}
.sb-toc__card{
	background:var(--sb-surface);border:2.5px solid var(--sb-ink);
	box-shadow:var(--sb-shadow-md);border-radius:18px;padding:16px;
}
.sb-toc__label{margin:0;font-weight:900;font-size:11px;letter-spacing:1.4px;text-transform:uppercase;color:var(--sb-text-faint)}
.sb-toc__list{display:flex;flex-direction:column;gap:9px;margin-top:12px}
.sb-toc__list a{
	display:flex;gap:7px;align-items:baseline;
	font-weight:800;font-size:12.5px;line-height:1.4;color:var(--sb-text);text-decoration:none;
}
.sb-toc__list a:hover{color:var(--sb-heading);text-decoration:none}
.sb-toc__list a.is-current{color:var(--sb-primary-ink)}
.sb-toc__n{font-weight:900;color:var(--sb-text-faint);flex:none}
.sb-toc__list a.is-current .sb-toc__n{color:var(--sb-primary-ink)}
.sb-toc__rule{height:2px;background:var(--sb-hairline);border:0;margin:14px 0}
.sb-toc__share{display:flex;gap:8px}
.sb-toc__btn{
	width:34px;height:34px;border-radius:11px;
	background:var(--sb-surface-2);border:2px solid var(--sb-ink);
	display:grid;place-items:center;font-size:14px;color:var(--sb-heading);cursor:pointer;
	text-decoration:none;transition:transform .06s;
}
.sb-toc__btn:hover{background:var(--sb-warm);text-decoration:none}
.sb-toc__btn:active{transform:translateY(2px)}
.sb-toc__toast{margin:10px 0 0;font-weight:800;font-size:11.5px;color:var(--sb-success-ink);min-height:1em}

/* byline */
.sb-byline{display:flex;align-items:center;gap:14px;margin-top:22px}
.sb-byline__avatar{
	width:48px;height:48px;flex:none;border-radius:50%;
	background:var(--sb-mint);border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);
	display:grid;place-items:center;font-family:var(--sb-font-display);font-size:20px;color:var(--sb-heading);
}
.sb-byline__name{margin:0;font-weight:900;font-size:14px;color:var(--sb-heading)}
.sb-byline__meta{margin:2px 0 0;font-weight:800;font-size:12.5px;color:var(--sb-text-dim)}
.sb-byline__reviewed{color:var(--sb-success-ink)}

.sb-article__cover{margin-top:26px;border-radius:var(--sb-r-xl);overflow:hidden;border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg)}
.sb-article__cover--empty{height:340px}

/* body */
.sb-article__body{margin-top:30px}
.sb-article__body > p:first-child{font-size:19px;line-height:1.7;color:var(--sb-heading)}
.sb-article__body h2{
	font-family:var(--sb-font-display);font-weight:400;font-size:27px;
	line-height:1.2;margin:34px 0 12px;color:var(--sb-heading);scroll-margin-top:96px;
}
.sb-article__body h3{font-family:var(--sb-font-display);font-weight:400;font-size:22px;margin:26px 0 10px;color:var(--sb-heading)}
.sb-article__body p,.sb-article__body li{font-size:16.5px;line-height:1.8}
.sb-article__body ul,.sb-article__body ol{padding-left:22px;display:flex;flex-direction:column;gap:8px}
.sb-article__body a{text-decoration:underline;text-underline-offset:3px}
/* pull quote */
/* Article tables. The theme had no table rules at all, so the comparison
   tables the articles lean on rendered as bare columns of text with nothing
   separating them. Same card idiom as the rest of the design: thick indigo
   border, rounded corners, hard offset shadow.

   The wrapper scrolls rather than the page: a four-column table cannot shrink
   below its content, and without this the whole document scrolls sideways on a
   phone. */
.sb-article__body figure.wp-block-table{
	margin:26px 0;overflow-x:auto;-webkit-overflow-scrolling:touch;
	border:var(--sb-bw) solid var(--sb-ink);border-radius:var(--sb-r-lg);
	box-shadow:0 6px 0 var(--sb-ink);background:var(--sb-surface);
}
.sb-article__body table{
	width:100%;min-width:420px;border-collapse:collapse;
	font-size:15.5px;line-height:1.55;
}
.sb-article__body thead th{
	background:var(--sb-warm);color:var(--sb-heading);
	font-weight:900;font-size:13px;letter-spacing:.4px;text-transform:uppercase;
	text-align:left;padding:13px 16px;
	border-bottom:2.5px solid var(--sb-ink);
}
.sb-article__body tbody td{
	padding:12px 16px;vertical-align:top;
	border-bottom:2px solid var(--sb-hairline,rgba(51,37,74,.14));
}
.sb-article__body tbody tr:last-child td{border-bottom:0}
.sb-article__body tbody tr:nth-child(even){background:rgba(51,37,74,.035)}
/* Second and later columns are almost always the number — keep them together. */
.sb-article__body td + td,.sb-article__body th + th{white-space:nowrap}
.sb-article__body td:first-child{white-space:normal}
/* ...except a legal processors table, which is prose in every column. */
.sb-article__body table.sb-table--prose td + td,
.sb-article__body table.sb-table--prose th + th{white-space:normal}
[data-theme="dark"] .sb-article__body tbody tr:nth-child(even){background:rgba(255,255,255,.04)}
[data-theme="dark"] .sb-article__body tbody td{border-bottom-color:rgba(255,255,255,.12)}

@media (max-width:600px){
	.sb-article__body table{font-size:14.5px}
	.sb-article__body thead th,.sb-article__body tbody td{padding:10px 12px}
}

.sb-article__body blockquote{
	border-left:6px solid var(--sb-primary);padding:6px 0 6px 22px;margin:30px 0;
	background:none;border-radius:0;
}
.sb-article__body blockquote p{
	font-family:var(--sb-font-display);font-weight:400;font-size:24px;line-height:1.4;
	color:var(--sb-heading);margin:0;text-wrap:pretty;
}

/* formula callout */
.sb-formula{background:var(--sb-warm);border:var(--sb-bw) dashed var(--sb-warm-border);border-radius:22px;padding:24px 26px;margin:22px 0}
.sb-formula__label{margin:0;font-weight:900;font-size:12px;letter-spacing:1.5px;text-transform:uppercase;color:var(--sb-warm-ink)}
.sb-formula__title{margin:10px 0 0;font-family:var(--sb-font-display);font-size:24px;line-height:1.3;color:var(--sb-warm-ink)}
.sb-formula__body p{margin:10px 0 0;font-weight:700;font-size:14.5px;line-height:1.7;color:var(--sb-warm-text)}

/* conversion rows */
.sb-convert{
	display:flex;align-items:center;gap:14px;margin:11px 0 0;
	background:var(--sb-surface);border:2.5px solid var(--sb-ink);
	box-shadow:var(--sb-shadow-md);border-radius:16px;padding:14px 18px;
}
.sb-convert__icon{font-size:24px;flex:none}
.sb-convert__from{flex:1;font-weight:800;font-size:15.5px;color:var(--sb-heading)}
.sb-convert__to{font-family:var(--sb-font-display);font-size:17px;color:var(--sb-primary-ink);flex:none}

/* author box */
.sb-authorbox{
	display:flex;align-items:center;gap:18px;margin-top:26px;
	background:var(--sb-surface);border:var(--sb-bw) solid var(--sb-ink);
	box-shadow:var(--sb-shadow-lg);border-radius:22px;padding:22px;
	border-top:var(--sb-bw) solid var(--sb-ink);
}
.sb-authorbox__avatar{
	width:66px;height:66px;flex:none;border-radius:50%;
	background:var(--sb-mint);border:var(--sb-bw) solid var(--sb-ink);
	display:grid;place-items:center;font-family:var(--sb-font-display);font-size:26px;color:var(--sb-heading);
}
.sb-authorbox__body{flex:1;min-width:0}
.sb-authorbox__name{margin:0;font-family:var(--sb-font-display);font-size:19px;color:var(--sb-heading)}
.sb-authorbox__bio{margin:5px 0 0;font-weight:700;font-size:14px;line-height:1.65}
.sb-authorbox__more{flex:none;font-weight:900;font-size:13.5px;white-space:nowrap}

.sb-readnext__title{font-size:26px}
.sb-readnext .sb-grid-posts{margin-top:20px}

.sb-breadcrumb{display:flex;gap:9px;flex-wrap:wrap;font-weight:800;font-size:12.5px;color:var(--sb-text-faint)}
/* tokens.css sets `img,svg{display:block;max-width:100%}` with no height rule.
   Any image carrying real width/height attributes — which every WordPress-
   generated <img> does — then gets its width clamped to the column while the
   height attribute still applies, so a 16:9 illustration renders stretched into
   a near-square. height:auto restores the ratio. Global, because it is not
   specific to article bodies: post cards, mascots and uploads all inherit it.
   Excludes the two places that deliberately size an image to its frame. */
img:not(.sb-postcard__cover img):not(.sb-mascot__stack img){height:auto}

.sb-article__body img{border-radius:var(--sb-r-lg);border:2.5px solid var(--sb-ink);margin:18px 0}
.sb-breadcrumb a{color:var(--sb-text-dim)}
.sb-share{display:flex;gap:10px;align-items:center}
.sb-share a,.sb-share button{width:40px;height:40px;border-radius:11px;border:2.5px solid var(--sb-ink);background:var(--sb-surface-2);display:grid;place-items:center;color:var(--sb-heading);cursor:pointer;font-size:15px}
.sb-share a:hover,.sb-share button:hover{text-decoration:none;background:var(--sb-warm)}

/* ---------- search form ---------- */
.sb-searchform{flex-direction:row;gap:10px;align-items:center;max-width:520px}
.sb-searchform input[type=search]{
	flex:1;height:48px;padding:0 14px;border:2.5px solid var(--sb-ink);border-radius:14px;
	background:var(--sb-surface-2);font:800 15px var(--sb-font-body);color:var(--sb-heading);
}
.sb-searchform input[type=search]:focus{outline:3px solid var(--sb-purple);outline-offset:2px}

/* ---------- contact (artboard "Web Contact") ---------- */
.sb-contact{display:flex;gap:44px;align-items:flex-start}
.sb-contact__main{flex:1.25;min-width:0}
.sb-contact__title{font-size:clamp(32px,4.4vw,46px);line-height:1.1;margin-top:10px}
.sb-contact__notice{display:block;margin-top:22px}
.sb-contact__side{flex:none;width:330px;display:flex;flex-direction:column;gap:16px}

.sb-cform{
	margin-top:28px;background:var(--sb-surface);
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	border-radius:var(--sb-r-xl);padding:28px;
	display:flex;flex-direction:column;gap:18px;
}
.sb-cform__row{display:flex;gap:16px}
.sb-cform__row .sb-field{flex:1;min-width:0}
.sb-field{display:flex;flex-direction:column;gap:7px;margin:0}
.sb-field__label{font-weight:900;font-size:11.5px;letter-spacing:1.2px;text-transform:uppercase;color:var(--sb-text-faint);padding:0}
.sb-field input,.sb-field textarea{
	height:52px;padding:0 15px;border:2.5px solid var(--sb-hairline);border-radius:15px;
	background:var(--sb-surface-2);font:800 14.5px/1.7 var(--sb-font-body);color:var(--sb-heading);width:100%;
}
.sb-field textarea{height:auto;min-height:130px;padding:14px 15px}
.sb-field input::placeholder,.sb-field textarea::placeholder{color:var(--sb-text-faint);font-weight:700}
.sb-field input:focus,.sb-field textarea:focus{
	outline:none;border-color:var(--sb-ink);box-shadow:0 3px 0 var(--sb-ink);
}
.sb-field input:focus-visible,.sb-field textarea:focus-visible{outline:3px solid var(--sb-purple);outline-offset:2px}

/* subject chips are real radios — they submit a value and work by keyboard */
.sb-chips{border:0;padding:0;margin:0;min-width:0}
.sb-chips__row{display:flex;flex-wrap:wrap;gap:9px;margin-top:8px}
.sb-chip{cursor:pointer}
.sb-chip input{position:absolute;opacity:0;width:0;height:0}
.sb-chip span{
	display:inline-block;border:2px solid var(--sb-hairline);border-radius:12px;padding:8px 14px;
	background:var(--sb-surface-2);font-weight:800;font-size:13px;color:var(--sb-heading);
	transition:transform .06s,box-shadow .06s;
}
.sb-chip input:checked + span{
	background:var(--sb-primary);color:var(--sb-ink);
	border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);font-weight:900;
}
.sb-chip input:focus-visible + span{outline:3px solid var(--sb-purple);outline-offset:3px}

.sb-cform__foot{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap}
.sb-check{display:flex;align-items:center;gap:10px;cursor:pointer;max-width:380px}
.sb-check input{position:absolute;opacity:0;width:0;height:0}
.sb-check__box{
	width:26px;height:26px;flex:none;border-radius:9px;
	background:var(--sb-surface-2);border:2.5px solid var(--sb-ink);
	display:grid;place-items:center;
}
.sb-check__box::after{content:"✓";font-weight:900;font-size:14px;color:var(--sb-ink);opacity:0}
.sb-check input:checked + .sb-check__box{background:var(--sb-primary)}
.sb-check input:checked + .sb-check__box::after{opacity:1}
.sb-check input:focus-visible + .sb-check__box{outline:3px solid var(--sb-purple);outline-offset:3px}
.sb-check__text{font-weight:800;font-size:13px;line-height:1.45;color:var(--sb-text)}

/* support cards */
.sb-scard{border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);border-radius:22px;padding:22px}
.sb-scard__icon{font-size:26px;line-height:1}
.sb-scard__title{font-size:19px;margin-top:10px}
.sb-scard__lead{margin:6px 0 0;font-weight:800;font-size:14.5px;overflow-wrap:anywhere}
.sb-scard__note{margin:6px 0 0;font-weight:700;font-size:13.5px;line-height:1.65}
.sb-scard__link{display:inline-flex;margin-top:12px;font-weight:900;font-size:13.5px}
.sb-scard--mint{background:var(--sb-mint)}
.sb-scard--mint .sb-scard__lead a{color:var(--sb-success-ink)}
.sb-scard--mint .sb-scard__note{color:var(--sb-success-ink)}
.sb-scard--warm{background:var(--sb-warm)}
.sb-scard--warm .sb-scard__note{color:var(--sb-warm-text)}
.sb-scard--warm .sb-scard__link{color:var(--sb-warm-ink)}
.sb-scard--urgent{background:var(--sb-ink);border-color:var(--sb-ink);box-shadow:0 6px 0 var(--sb-primary)}
.sb-scard--urgent .sb-scard__title{color:var(--sb-footer-text)}
.sb-scard--urgent .sb-scard__note{color:#B9A6C4}
.sb-scard--urgent .sb-scard__note b{color:var(--sb-footer-text)}
.sb-scard--urgent .sb-scard__link{color:var(--sb-accent)}
.sb-hp{position:absolute!important;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ---------- 404 (design: docs/03-pages.md · G) ---------- */
.sb-404{display:flex;align-items:center;gap:40px;padding-bottom:34px}
.sb-404__copy{flex:1;min-width:0}
.sb-404__num{
	font-family:var(--sb-font-display);font-size:118px;line-height:.92;
	letter-spacing:-2px;color:var(--sb-heading);margin:0;
}
.sb-404__actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.sb-404__ways{padding-top:0}

/* the spilled-glass panel */
.sb-404__panel{
	flex:none;width:430px;height:320px;position:relative;overflow:hidden;
	border-radius:var(--sb-r-2xl);background:#FFE1B8;
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
}
[data-theme="dark"] .sb-404__panel{background:var(--sb-surface-2)}
.sb-404__spark{position:absolute;color:#B07A2E;animation:sb-twinkle 2.6s ease-in-out infinite}
[data-theme="dark"] .sb-404__spark{color:var(--sb-accent)}
.sb-404__spark--1{left:34px;top:30px;font-size:15px}
.sb-404__spark--2{right:44px;top:56px;font-size:12px;animation-delay:-1.1s}
.sb-404__glass{position:absolute;left:52px;top:44px;transform:rotate(104deg);animation:sb-bob 4.4s ease-in-out infinite}
.sb-404__spill{position:absolute;left:150px;bottom:44px}
.sb-404__puddle{display:block;width:190px;height:34px;border-radius:50%;background:var(--sb-accent);border:var(--sb-bw) solid var(--sb-ink)}
.sb-404__blob{position:absolute;border-radius:50%;background:var(--sb-accent);border:var(--sb-bw) solid var(--sb-ink);display:block}
.sb-404__blob--l{left:-22px;top:6px;width:26px;height:16px}
.sb-404__blob--r{right:-16px;top:12px;width:18px;height:12px}
.sb-404__bubble{position:absolute;border-radius:50%;background:var(--sb-surface);border:var(--sb-bw) solid var(--sb-ink);display:block}
.sb-404__bubble--1{left:176px;bottom:74px;width:26px;height:26px}
.sb-404__bubble--2{left:202px;bottom:58px;width:19px;height:19px}
.sb-404__bubble--3{left:222px;bottom:70px;width:13px;height:13px;border-width:2.5px}
.sb-404__drop{position:absolute;animation:sb-drop 1.7s ease-in infinite}
.sb-404__drop--1{left:246px;bottom:96px;font-size:20px}
.sb-404__drop--2{left:262px;bottom:104px;font-size:14px;animation-delay:-.8s}
.sb-404__mascot{position:absolute;right:14px;bottom:26px;animation:sb-bob 3.2s ease-in-out infinite}
@keyframes sb-drop{
	0%{transform:translateY(-6px) scale(.7);opacity:0}
	30%{opacity:1}
	100%{transform:translateY(26px) scale(1);opacity:0}
}

/* recovery cards */
.sb-waycard{
	display:flex;align-items:center;gap:14px;
	background:var(--sb-surface);border:var(--sb-bw) solid var(--sb-ink);
	box-shadow:var(--sb-shadow-lg);border-radius:22px;padding:18px 20px;
	text-decoration:none;transition:transform .06s,box-shadow .06s;
}
.sb-waycard:hover{text-decoration:none}
.sb-waycard:active{transform:translateY(3px);box-shadow:0 3px 0 var(--sb-ink)}
.sb-waycard__icon{
	display:grid;place-items:center;width:52px;height:52px;flex:none;
	border-radius:16px;border:2.5px solid var(--sb-ink);font-size:24px;
}
.sb-waycard__icon--rose{background:#FFEDE7}
.sb-waycard__icon--mint{background:var(--sb-mint)}
.sb-waycard__icon--lilac{background:var(--sb-lilac)}
[data-theme="dark"] .sb-waycard__icon--rose{background:var(--sb-surface-2)}
.sb-waycard__body{flex:1;min-width:0}
.sb-waycard__title{display:block;font-family:var(--sb-font-display);font-size:18px;color:var(--sb-heading)}
.sb-waycard__sub{display:block;margin-top:2px;font-weight:700;font-size:13px;color:var(--sb-text-dim)}
.sb-waycard__chev{font-weight:900;font-size:16px;color:var(--sb-text-faint);flex:none}

/* ---------- cookie consent ---------- */
.sb-consent{position:fixed;left:0;right:0;bottom:0;padding:14px var(--sb-gutter) 18px;z-index:100;display:grid;justify-items:center}
.sb-consent[hidden]{display:none}
.sb-consent__card{max-width:760px;width:100%;display:flex;justify-content:space-between;align-items:center;gap:18px;flex-wrap:wrap}
.sb-consent__text{margin:0;flex:1 1 320px;font-size:14px;line-height:1.55}
.sb-consent__btns{display:flex;gap:10px;flex:none}

/* ---------- real app screenshots (template-parts/app-shot.php) ----------
   The capture already contains the device status bar and Dynamic Island, so
   this body draws no notch — one would land on top of the real one. Aspect is
   pinned to the capture's own 640×1391 (1:2.1734) so nothing is squashed. */
.sb-phone{
	--sb-phone-w:236px;
	position:relative;flex:none;margin:0;
	width:var(--sb-phone-w);
	padding:5px;
	background:#12161C;
	border-radius:calc(var(--sb-phone-w) / 7.2);
	box-shadow:0 0 0 3px #1B222C, 0 7px 0 var(--sb-ink), 0 18px 40px rgba(20,11,34,.24);
}
.sb-phone--sm{--sb-phone-w:190px}
.sb-phone--lg{--sb-phone-w:288px}
.sb-phone__screen{
	display:block;width:100%;height:auto;
	border-radius:calc(var(--sb-phone-w) / 9);
	background:var(--sb-page);
}
[data-theme="dark"] .sb-phone{box-shadow:0 0 0 3px #2A3341, 0 7px 0 var(--sb-ink), 0 18px 40px rgba(0,0,0,.5)}

/* The screenshot strip. It scrolls sideways rather than wrapping: eight phones
   wrapped into rows read as a contact sheet, and the point is a walkthrough. */
.sb-shots{
	display:flex;gap:26px;align-items:flex-start;
	overflow-x:auto;-webkit-overflow-scrolling:touch;
	padding:6px var(--sb-gutter) 30px;
	margin:0 calc(var(--sb-gutter) * -1);
	scroll-snap-type:x proximity;
	scrollbar-width:thin;
}
.sb-shots::-webkit-scrollbar{height:10px}
.sb-shots::-webkit-scrollbar-thumb{background:var(--sb-hairline);border-radius:99px}
.sb-shot{display:flex;flex-direction:column;align-items:center;gap:12px;flex:none;scroll-snap-align:center;width:236px}
.sb-shot__cap{margin:0;text-align:center}
.sb-shot__cap b{display:block;font-family:var(--sb-font-display);font-weight:400;font-size:17px;color:var(--sb-heading)}
.sb-shot__cap span{display:block;margin-top:3px;font-weight:700;font-size:13.5px;line-height:1.5;color:var(--sb-text-dim)}
/* A row of phones beside prose — features page. */
.sb-fshot{
	display:flex;gap:52px;align-items:center;justify-content:center;flex-wrap:wrap;
	margin-top:56px;
}
/* Explicit, not :nth-child(even) — the section head is a sibling and would
   flip the parity of every row beneath it. */
.sb-fshot--flip{flex-direction:row-reverse}
.sb-fshot__copy{flex:1 1 320px;min-width:0;max-width:440px}
.sb-fshot__art{display:flex;gap:20px;flex:none;align-items:flex-start}
@media (max-width:900px){
	.sb-fshot,.sb-fshot--flip{flex-direction:column;gap:28px;margin-top:44px}
	.sb-fshot__copy{max-width:none;text-align:center}
}
@media (max-width:600px){
	.sb-shots{gap:18px}
	.sb-shot,.sb-phone{--sb-phone-w:200px}
	.sb-shot{width:200px}
}

/* ---------- footer (design: "Web Home" artboard) ---------- */
.sb-footer{padding:58px var(--sb-gutter) 26px}
.sb-footer__cols{display:flex;gap:60px;flex-wrap:wrap}
.sb-footer__brand{flex:1.3 1 240px;min-width:0}
.sb-footer__logo{display:flex;align-items:center;gap:11px}
.sb-footer__logo:hover{text-decoration:none}
.sb-footer__mark{
	width:38px;height:38px;border-radius:12px;flex:none;
	background:var(--sb-purple) url("../img/app-icon.svg") center/cover no-repeat;
	border:2.5px solid var(--sb-footer-text);
}
.sb-footer__word{font-family:var(--sb-font-display);font-size:21px;color:var(--sb-footer-text)}
.sb-footer__tagline{margin:14px 0 0;max-width:290px;font-weight:700;font-size:14px;line-height:1.7;color:var(--sb-footer-dim)}
.sb-footer__col{flex:1 1 150px;min-width:0;display:flex;flex-direction:column;align-items:flex-start}
.sb-footer__col-title{margin:0 0 14px;font-weight:900;font-size:12px;letter-spacing:1.6px;text-transform:uppercase;color:var(--sb-footer-dim)}
.sb-footer__col a{display:block;padding:0;margin-bottom:9px;font-weight:800;font-size:14px}
.sb-footer__social{display:flex;gap:9px;margin-top:8px}
.sb-footer__social a{width:34px;height:34px;margin:0;border-radius:11px;background:var(--sb-footer-toggle);border:2px solid var(--sb-footer-line);display:grid;place-items:center;color:var(--sb-footer-text)}
.sb-footer__social a:hover{background:var(--sb-footer-line);text-decoration:none}
.sb-footer__bottom{
	display:flex;align-items:center;justify-content:space-between;gap:22px;flex-wrap:wrap;
	border-top:2px solid var(--sb-footer-line);margin-top:34px;padding-top:20px;
}
.sb-footer__bottom-right{display:flex;align-items:center;gap:22px;flex-wrap:wrap}

/* ---------- pagination ---------- */
.sb-pagination{display:flex;gap:8px;justify-content:center;margin-top:34px;flex-wrap:wrap}
.sb-pagination .page-numbers{display:inline-grid;place-items:center;min-width:42px;height:42px;padding:0 12px;border:2.5px solid var(--sb-ink);border-radius:12px;background:var(--sb-surface-2);color:var(--sb-heading);font-weight:900;text-decoration:none}
.sb-pagination .current{background:var(--sb-primary);color:#fff}
[data-theme="dark"] .sb-pagination .current{color:#241A33}

/* ============================================================
   ACCESSIBILITY CORRECTIONS to the handoff palette
   ------------------------------------------------------------
   docs/08-qa-accessibility.md requires 4.5:1 for body text and for
   `--sb-text-dim` / `--sb-footer-dim`, and 3:1 for `--sb-text-faint`.
   Measured against the handoff mock itself, four pairings miss it:

     white on --sb-primary  (every primary button)   2.94:1
     --sb-text-dim   nav on --sb-surface             3.78:1
     --sb-footer-dim on the footer                   2.76:1
     --sb-text-faint meta on --sb-page               2.05:1

   These are the smallest hue-preserving corrections that clear the bar
   (10–21% darker/lighter). They live HERE, not in tokens.css, so the
   shared design-system file stays a clean copy of the handoff — and so
   this whole block can be deleted in one go if the brand decides to keep
   the original values. If they are accepted, mirror them back into the
   iOS token set so web and app stay in sync.
   ============================================================ */
/* Scoped with :not([data-theme="dark"]) — a bare :root here would sit LATER in
   the cascade than tokens.css's [data-theme="dark"] block at equal specificity
   and silently repaint dark mode with the light palette. */
/* White text on --sb-primary measures 2.64:1 — below the 4.5:1 AA floor — and
   this has now bitten three separate components (the language picker's selected
   row, the blog CTA button, the small in-article CTA). --sb-on-primary is the
   same coral darkened until white is legible on it, 5.4:1, and it is deliberately
   theme-independent: every surface that uses it is coral in both themes, so a
   token that flips would reintroduce the bug in dark mode. */
:root{--sb-on-primary:#C4342B}

:root:not([data-theme="dark"]){
	--sb-text-dim:#786A7F;       /* was #8B7A93 — 3.78:1 → 4.66:1 on the page bg */
	--sb-text-faint:#786B7F;     /* was #B9A6C4 — 2.05:1 → 4.53:1 */
	--sb-footer-dim:#9686AA;     /* was #7A6693 — 2.76:1 → 4.54:1 */
	--sb-primary-ink:#D43A30;    /* was #D63B30 — 4.43:1 → 4.51:1 */
	--sb-primary-accent:#EE5C51; /* --sb-primary is 2.67:1 as text; this is 3.03:1 */
	--sb-success-ink:#1E7A5B;    /* --sb-success is 2.24:1 as text; this is 4.9:1 */
	--sb-purple-ink:#6B4AE0;     /* white on --sb-purple is 4.35:1; this is 5.70:1 */
	--sb-purple-text:#6B4AE0;    /* purple used AS TEXT; same value works on light */
}
[data-theme="dark"]{
	--sb-text-faint:#9384A9;     /* was #8C7BA3 — 4.05:1 on surface-2 → 4.52:1 */
	--sb-footer-dim:#907FA5;     /* was #7A6693 — 3.27:1 → 4.54:1 */
	--sb-primary-accent:var(--sb-primary-ink); /* already 7.5:1 in dark */
	--sb-success-ink:var(--sb-success);        /* 9.1:1 in dark */
	--sb-purple-ink:#7F64CF;                   /* white on #9D7CFF is 3.11:1; this is 4.54:1 */
	/* --sb-purple-ink is tuned for WHITE ON purple. Purple AS TEXT on a dark
	   surface needs the opposite adjustment, so it gets its own token. */
	--sb-purple-text:#B49BFF;                  /* 6.0:1 on --sb-surface */
}
/* The design already uses dark-on-primary in dark mode for exactly this
   reason; light mode kept a white label that reads at 2.94:1. Mirror the
   dark-mode decision so the candy fill survives and the label is legible. */
.sb-btn--primary{color:var(--sb-ink)}
.sb-nav a.sb-btn--primary,.sb-mobile-menu a.sb-btn--primary{color:var(--sb-ink)}
[data-theme="dark"] .sb-btn--primary,
[data-theme="dark"] .sb-nav a.sb-btn--primary,
[data-theme="dark"] .sb-mobile-menu a.sb-btn--primary{color:#241A33}
.sb-cta,.sb-pagination .current{color:var(--sb-ink)}
.sb-price__badge{background:var(--sb-purple-ink)}  /* --sb-purple is 4.35:1 under white */
.sb-skip{color:var(--sb-ink)}          /* white on --sb-primary is 2.94:1 */
/* The tinted full stop in the H1 is heading TEXT, not decoration — it needs
   3:1 like the rest of the headline, which --sb-primary itself does not reach. */
.sb-h1 .sb-dot{color:var(--sb-primary-accent)}

/* ---------- responsive (single breakpoint: 900px, per docs/01-tokens.md) ---------- */
@media (max-width:900px){
	.sb-hero__grid{grid-template-columns:1fr;gap:26px}
	.sb-hero__phone{min-height:560px}
	.sb-stats__grid,.sb-grid-posts,.sb-price{grid-template-columns:1fr}
	.sb-article-wrap{flex-direction:column;gap:26px}
	.sb-toc{position:static;width:100%}
	.sb-article{max-width:none}
	.sb-news{padding:26px}
	.sb-news__form{width:100%}
	.sb-news__form input[type=email]{flex:1}
	.sb-contact{flex-direction:column}
	.sb-contact__side{width:100%}
	.sb-cform__row{flex-direction:column}
	.sb-cform__foot{align-items:flex-start}
	.sb-band__grid{flex-direction:column;align-items:stretch;gap:30px}
	.sb-band__grid--reverse .sb-band__copy{order:0}
	.sb-visicard{width:100%}
	.sb-widgets{flex-direction:column;align-items:stretch}
	.sb-widget--sm,.sb-widget--lg{width:100%}
	.sb-yard__head{flex-direction:column;gap:18px}
	.sb-yard__caption{text-align:left}
	.sb-cal-row,.sb-404,.sb-cta{flex-direction:column;align-items:stretch}
	.sb-cta{padding:34px 26px}
	.sb-store-row--stacked{width:100%}
	.sb-cal,.sb-404__panel{width:100%}
	.sb-404__num{font-size:82px}
	.sb-menu-toggle{display:inline-flex}
	.sb-footer__cols{gap:32px}
	/* Touch targets ≥44px on mobile (docs/08-qa-accessibility.md). */
	.sb-btn,.sb-lang,.sb-share a,.sb-share button,.sb-lang__item{min-height:44px}
	.sb-theme{height:52px}
	.sb-theme__opt{height:44px}
	.sb-menu-toggle{min-width:44px}
}

/* ---------- shared profile (artboard "Web Profile share") ---------- */
.sb-header--slim{justify-content:space-between}
.sb-preview-note{
	display:flex;align-items:center;gap:10px;margin:0;
	padding:12px var(--sb-gutter);background:var(--sb-lilac);
	border-bottom:2.5px solid var(--sb-ink);
	font-weight:800;font-size:13px;color:var(--sb-lilac-ink);
}
.sb-profile__band{
	height:150px;position:relative;border-bottom:2.5px solid var(--sb-ink);
	background:linear-gradient(180deg,#FFE1B8 0%,#FFF3E4 100%);
}
[data-theme="dark"] .sb-profile__band{background:linear-gradient(180deg,var(--sb-surface-2) 0%,var(--sb-page) 100%)}
.sb-profile__sun{
	position:absolute;right:44px;top:30px;width:52px;height:52px;border-radius:50%;
	background:var(--sb-accent);border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-md);
	animation:sb-pulse 4s ease-in-out infinite;
}
@keyframes sb-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.08)}}
.sb-profile__spark{position:absolute;left:88px;top:64px;font-size:15px;color:var(--sb-accent);animation:sb-twinkle 2.6s ease-in-out infinite}
.sb-profile__head{padding-top:16px}
.sb-profile__row{display:flex;gap:26px;align-items:flex-end;flex-wrap:wrap}
/* The avatar overlaps the band. Lift the avatar itself, never the whole row —
   a negative margin on the row drops the name block over the band's rule
   (docs/02-components.md). */
.sb-profile__avatar{
	width:130px;height:130px;flex:none;border-radius:50%;overflow:hidden;
	background:var(--sb-mint);border:4px solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	display:grid;place-items:center;position:relative;top:-86px;margin-bottom:-52px;
}
.sb-profile__mascot{margin-top:8px;animation:sb-bob 3.6s ease-in-out infinite}
.sb-profile__id{flex:1;min-width:0;padding-bottom:8px}
.sb-profile__name{font-family:var(--sb-font-display);font-weight:400;font-size:clamp(26px,3.6vw,36px);line-height:1.1;color:var(--sb-heading);margin:0}
/* 👑 Plus, beside the name. The page only resolves for a subscriber (the API
   404s a lapsed one), so this is a statement of fact, not decoration. */
.sb-profile__plus{
	display:inline-flex;align-items:center;gap:5px;vertical-align:middle;
	margin-left:10px;padding:3px 10px;border-radius:999px;
	background:var(--sb-accent);border:2px solid var(--sb-ink);
	font-family:var(--sb-font-body);font-weight:900;font-size:12.5px;
	letter-spacing:.02em;color:var(--sb-ink);white-space:nowrap;
	transform:translateY(-3px);
}
.sb-profile__handle{margin:4px 0 0;font-weight:800;font-size:14.5px;color:var(--sb-text-dim)}
.sb-profile__mood{
	display:inline-flex;align-items:center;gap:9px;margin:12px 0 0;
	background:var(--sb-surface);border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);
	border-radius:14px;padding:8px 14px;font-weight:900;font-size:14px;color:var(--sb-heading);
}
.sb-profile__actions{display:flex;gap:12px;flex:none;padding-bottom:10px;flex-wrap:wrap}
.sb-btn--cheer{background:var(--sb-accent);color:var(--sb-ink)}
.sb-btn--message{background:var(--sb-purple-ink);color:#fff}

/* stat cards */
.sb-pstats{display:flex;gap:20px;margin-top:34px;flex-wrap:wrap}
.sb-pstat{
	flex:1 1 180px;background:var(--sb-surface);
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	border-radius:22px;padding:22px;text-align:center;
}
.sb-pstat--tilt-l{transform:rotate(-.6deg)}
.sb-pstat--tilt-r{transform:rotate(.6deg)}
.sb-pstat__icon{font-size:24px}
.sb-pstat__n{display:block;font-family:var(--sb-font-display);font-size:38px;line-height:1.15}
.sb-pstat__n--primary{color:var(--sb-primary-ink)}
.sb-pstat__n--success{color:var(--sb-success-ink)}
.sb-pstat__n--warm{color:var(--sb-warm-ink)}
.sb-pstat__l{display:block;font-weight:800;font-size:13.5px;color:var(--sb-text-dim)}
/* A section the owner keeps private: label only, no figure in the document. */
.sb-pstat--locked{
	background:var(--sb-page);border:var(--sb-bw) dashed var(--sb-hairline);box-shadow:none;
	display:flex;flex-direction:column;justify-content:center;
}
.sb-pstat__locked-title{display:block;margin-top:6px;font-weight:900;font-size:13px;color:var(--sb-text-dim)}
.sb-pstat__locked-note{display:block;margin-top:3px;font-weight:700;font-size:12px;color:var(--sb-text-faint)}

/* shared-section cards */
.sb-pgrid{display:flex;gap:20px;margin-top:20px;align-items:flex-start;flex-wrap:wrap}
.sb-pcard{
	background:var(--sb-surface);border:var(--sb-bw) solid var(--sb-ink);
	box-shadow:var(--sb-shadow-lg);border-radius:var(--sb-r-xl);padding:24px;
}
.sb-pcard--cal{flex:1.15 1 320px}
.sb-pcol{flex:1 1 300px;display:flex;flex-direction:column;gap:20px;min-width:0}
.sb-pcard__head{display:flex;justify-content:space-between;align-items:center;gap:12px}
.sb-pcard__title{font-family:var(--sb-font-display);font-weight:400;font-size:20px;color:var(--sb-heading);margin:0}
.sb-pcard__title--warm{font-size:18px;color:var(--sb-warm-ink)}
.sb-pcard__note{font-weight:900;font-size:12px;color:var(--sb-text-dim)}
.sb-pcard--cal .sb-cal__grid{margin-top:16px}
.sb-pcard--badges{background:var(--sb-warm);padding:20px 24px}

/* seven-day bars */
.sb-bars{display:flex;align-items:flex-end;gap:9px;height:96px;margin-top:14px}
.sb-bar{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:5px;height:100%}
.sb-bar__n{font-weight:900;font-size:11.5px;color:var(--sb-text-dim)}
.sb-bar__fill{
	width:100%;max-width:34px;background:var(--sb-accent);
	border:2.5px solid var(--sb-ink);border-radius:8px;
}
.sb-bar__fill.is-zero{background:var(--sb-success)}
/* The payload carries a LEVEL per day and no count (PublicDayCell), so the bar
   is coloured the way the calendar square above it is — same four meanings,
   same four fills, and no invented number over the top. */
.sb-bar__fill[data-l="clean"]{background:var(--sb-success)}
.sb-bar__fill[data-l="under"]{background:var(--sb-accent)}
.sb-bar__fill[data-l="over"]{background:#FF8A63}
.sb-bar__fill[data-l="unlogged"]{background:var(--sb-hairline)}
/* The yearly price under the monthly one on the Plus card. */
.sb-price__alt{margin:-6px 0 0;color:var(--sb-text-dim);font-weight:800}
/* A photo fills its disc; a mascot sits inside one. */
.sb-profile__photo{border-radius:50%;object-fit:cover}
.sb-bar__d{font-weight:800;font-size:11px;color:var(--sb-text-faint)}

/* badges */
.sb-badges{display:flex;gap:9px;margin-top:12px;flex-wrap:wrap}
.sb-badge{
	width:44px;height:44px;border-radius:50%;
	background:var(--sb-surface);border:2.5px solid var(--sb-ink);box-shadow:var(--sb-shadow-sm);
	display:grid;place-items:center;font-size:20px;
}
.sb-badge--more{font-family:var(--sb-font-display);font-size:14px;color:var(--sb-warm-ink)}

/* conversion + note */
.sb-pconvert{
	display:flex;align-items:center;justify-content:space-between;gap:26px;flex-wrap:wrap;
	margin-top:26px;background:var(--sb-mint);
	border:var(--sb-bw) solid var(--sb-ink);box-shadow:var(--sb-shadow-lg);
	border-radius:var(--sb-r-xl);padding:26px 28px;
}
.sb-pconvert__title{font-family:var(--sb-font-display);font-weight:400;font-size:22px;color:var(--sb-heading);margin:0}
.sb-pconvert__sub{margin:8px 0 0;font-weight:700;font-size:14.5px;color:var(--sb-success-ink)}
.sb-pnote{margin:20px 0 0;font-weight:700;font-size:12.5px;color:var(--sb-text-faint);text-align:center}

@media (max-width:900px){
	.sb-profile__row{align-items:flex-start}
	.sb-profile__actions{width:100%}
	.sb-profile__actions .sb-btn{flex:1}
	.sb-pconvert{flex-direction:column;align-items:flex-start}
}
