/* Self-hosted SUSE variable fonts - same-origin, no CDN egress; mirrors shells/web/src/styles/fonts.css,
   including its source ORDER: the shell copy under /fonts/ ships on every profile, the brand catalog
   under /catalog/fonts/ only under a pack that has one. Listing the catalog alone (as this did before
   2026-08-10) meant the whole docs site fell back to a system font on the neutral profile. */
@font-face{font-family:'SUSE';src:url('/fonts/SUSE[wght].woff2') format('woff2-variations'),url('/catalog/fonts/webfonts/SUSE[wght].woff2') format('woff2-variations');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:'SUSE';src:url('/fonts/SUSE-Italic[wght].woff2') format('woff2-variations'),url('/catalog/fonts/webfonts/SUSE-Italic[wght].woff2') format('woff2-variations');font-weight:100 900;font-style:italic;font-display:swap}
@font-face{font-family:'SUSE Mono';src:url('/fonts/SUSEMono[wght].woff2') format('woff2-variations'),url('/catalog/fonts/webfonts/SUSEMono[wght].woff2') format('woff2-variations');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:'SUSE Mono';src:url('/fonts/SUSEMono-Italic[wght].woff2') format('woff2-variations'),url('/catalog/fonts/webfonts/SUSEMono-Italic[wght].woff2') format('woff2-variations');font-weight:100 900;font-style:italic;font-display:swap}
/* Cinzel (SIL OFL 1.1, see /info/fonts/Cinzel-OFL.txt) - Roman inscriptional capitals,
   the same source Gill drew Perpetua Titling from. Self-hosted, not fetched from
   fonts.gstatic.com: a third-party request on every docs page would contradict what
   server-surface.md tells the reader. Latin subset only, 26 KB, loaded on one page. */
@font-face{font-family:'Cinzel';src:url('/info/fonts/cinzel-latin.woff2') format('woff2-variations');font-weight:400 900;font-style:normal;font-display:swap;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+2000-206F,U+2122,U+2212}
:root {
  --font-brand: 'SUSE', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'SUSE Mono', ui-monospace, monospace;
}
:root {
  --safe-top: max(env(safe-area-inset-top, 0px), var(--safe-top-fb, 0px));
  --safe-bottom: max(env(safe-area-inset-bottom, 0px), var(--safe-bottom-fb, 0px));
  --safe-left: max(env(safe-area-inset-left, 0px), var(--safe-left-fb, 0px));
  --safe-right: max(env(safe-area-inset-right, 0px), var(--safe-right-fb, 0px));
}
:root {
  --chrome-h: calc(2.6rem * var(--a11y-fs, 1));   
  --chrome-top: calc(0.5rem + var(--safe-top));    
  --chrome-inset: 2rem;    
  --chrome-grow: calc(2.6rem * (var(--a11y-fs, 1) - 1));
}
:root {
  --grid-gap: 2rem;
  --grid-gap-tight: 12px;
}
@media (max-width: 640px) {
  :root {
    --grid-gap: var(--grid-gap-tight);
  }
}
@media (max-width: 640px) {
  :root {
    --chrome-top: calc(1.25rem + var(--safe-top));
  }
}
@media (pointer: coarse) {
  :root {
    --chrome-h: 44px;
  }
}
@media (pointer: coarse) {
  html[data-a11y-text="large"] {
    --chrome-h: calc(44px * var(--a11y-fs));
  }
}
:root {
  --vf-ai-1: 276 86% 67%;  --vf-ai-2: 262 74% 48%;  --vf-ai: 270 80% 58%;
}
:root {
  --track-rail: hsl(var(--muted) / 0.55);
}
:root {
  --preview-surface: hsl(var(--muted) / 0.6);
  --preview-checker: repeating-conic-gradient(
    hsl(var(--muted-foreground) / .05) 0% 25%,
    transparent 0% 50%) 50% / 14px 14px;
}
:root {
  --track-tier-1: 28%;
  --track-tier-2: 14%;
  --track-tier-3: 8%;
  --track-tier-beyond: 0%;
}
[data-theme="dark"],
[data-theme="brand"] {
  --track-tier-1: 46%;
  --track-tier-2: 26%;
  --track-tier-3: 15%;
}
:root,
[data-theme="light"] {
  color-scheme: light;
  --background:             0 0% 100%;
  --foreground:             224 71% 4%;
  --foreground-canvas:      224 71% 4%;
  --card:                   0 0% 99%;
  --card-foreground:        224 71% 4%;
  --popover:                0 0% 100%;
  --popover-foreground:     224 71% 4%;
  --primary:                171 62% 12%;      
  --primary-foreground:     0 0% 100%;
  --secondary:              210 40% 96%;
  --secondary-foreground:   224 71% 4%;
  --muted:                  210 40% 96%;
  --muted-foreground:       215 20% 38%;      
  --accent:                 210 40% 94%;
  --accent-foreground:      224 71% 4%;
  --destructive:            0 72% 51%;
  --destructive-foreground: 0 0% 100%;
  --border:                 214 28% 84%;
  --input:                  214 28% 84%;
  --ring:                   171 62% 12%;
  --store-1:                171 60% 20%;
  --store-2:                166 50% 32%;
  --store-3:                159 46% 43%;
  --store-4:                150 52% 55%;
  --store-5:                140 55% 65%;
  --store-other:            205 10% 62%;
  --radius:                 1rem;
}
[data-theme="dark"] {
  color-scheme: dark;
  --background:             224 71% 4%;
  --foreground:             213 31% 91%;
  --foreground-canvas:      213 31% 91%;   
  --card:                   222 47% 7%;
  --card-foreground:        213 31% 91%;
  --popover:                222 47% 7%;
  --popover-foreground:     213 31% 91%;
  --primary:                151 57% 46%;      
  --primary-foreground:     0 0% 100%;        
  --secondary:              217 33% 14%;
  --secondary-foreground:   213 31% 91%;
  --muted:                  217 33% 14%;
  --muted-foreground:       215 20% 76%;      
  --accent:                 217 33% 18%;
  --accent-foreground:      213 31% 91%;
  --destructive:            0 63% 38%;
  --destructive-foreground: 213 31% 91%;
  --border:                 217 33% 18%;
  --input:                  217 33% 18%;
  --ring:                   151 57% 46%;
  --store-1:                151 57% 46%;
  --store-2:                160 50% 54%;
  --store-3:                170 46% 60%;
  --store-4:                150 58% 70%;
  --store-5:                140 60% 78%;
  --store-other:            215 12% 46%;
  --radius:                 1rem;
}
[data-theme="brand"] {
  color-scheme: dark;
  --background:             171 62% 12%;      
  --foreground:             160 30% 92%;
  --foreground-canvas:      160 30% 92%;      
  --card:                   171 55% 17%;
  --card-foreground:        160 30% 92%;
  --popover:                171 55% 17%;
  --popover-foreground:     160 30% 92%;
  --primary:                151 57% 46%;      
  --primary-foreground:     0 0% 100%;        
  --secondary:              171 48% 21%;
  --secondary-foreground:   160 30% 92%;
  --muted:                  171 48% 20%;
  --muted-foreground:       160 18% 86%;      
  --accent:                 171 48% 22%;
  --accent-foreground:      160 30% 92%;
  --destructive:            0 55% 42%;
  --destructive-foreground: 160 30% 92%;
  --border:                 171 36% 33%;
  --input:                  171 36% 33%;
  --ring:                   151 57% 46%;
  --store-1:                151 57% 52%;
  --store-2:                146 52% 60%;
  --store-3:                160 46% 64%;
  --store-4:                140 58% 72%;
  --store-5:                132 60% 79%;
  --store-other:            171 16% 54%;
  --radius:                 1rem;
}
html[data-a11y-contrast="high"] {
  --track-rail: hsl(var(--muted) / 0.9);
}
html[data-a11y-contrast="high"]:not([data-theme="dark"]):not([data-theme="brand"]) {
  --card:                   210 24% 97%;   
  --muted-foreground:       215 32% 22%;   
  --border:                 214 30% 38%;   
  --input:                  214 32% 30%;   
  --ring:                   171 90% 12%;   
  --destructive:            0 80% 34%;     
  --store-1:                171 62% 16%;
  --store-2:                166 55% 27%;
  --store-3:                159 52% 38%;
  --store-4:                150 58% 48%;
  --store-5:                140 60% 57%;
  --store-other:            205 14% 42%;   
}
html[data-a11y-contrast="high"][data-theme="dark"] {
  --primary:                147.6 75% 67.1%; 
  --primary-foreground:     0 0% 0%;         
  --ring:                   147.6 75% 67.1%;
  --foreground:             213 45% 98%;   
  --card:                   222 47% 9%;    
  --card-foreground:        213 45% 98%;
  --popover:                222 47% 11%;   
  --popover-foreground:     213 45% 98%;
  --secondary:              217 33% 20%;   
  --secondary-foreground:   213 45% 98%;
  --muted:                  217 33% 17%;   
  --muted-foreground:       213 35% 86%;   
  --accent:                 217 33% 26%;   
  --accent-foreground:      213 45% 98%;
  --border:                 215 30% 55%;   
  --input:                  215 32% 62%;   
  --ring:                   213 45% 98%;
  --destructive:            0 72% 44%;     
  --destructive-foreground: 213 45% 98%;
  --store-other:            215 16% 66%;   
}
html[data-a11y-contrast="high"][data-theme="brand"] {
  --primary:                147.6 75% 67.1%; 
  --primary-foreground:     0 0% 0%;         
  --foreground:             0 0% 100%;     
  --card-foreground:        0 0% 100%;
  --popover-foreground:     0 0% 100%;
  --secondary-foreground:   0 0% 100%;
  --accent-foreground:      0 0% 100%;
  --muted-foreground:       0 0% 88%;      
  --border:                 0 0% 72%;      
  --input:                  0 0% 80%;      
  --ring:                   147.6 75% 67.1%; 
  --destructive:            0 72% 44%;     
  --destructive-foreground: 0 0% 100%;
  --store-other:            0 0% 68%;      
}
/* Bridge: the docs' legacy token names, expressed in the app's design tokens above, so the
   whole docs stylesheet follows the app's [data-theme] light/dark/brand system and - inside
   the app shell - the active brand. Neutrals/surfaces map cleanly; the ACCENT (--green ->
   --primary) is the one design choice to review: the app's primary is deep teal in light,
   pine green in dark/brand, so light-mode links become teal rather than green. */
:root{
  --page:hsl(var(--background));
  --text:hsl(var(--foreground));
  --muted:hsl(var(--muted-foreground));
  --border:hsl(var(--border));
  --pale:hsl(var(--muted));
  --green:hsl(var(--primary));
  --dark:hsl(var(--foreground));
  --light:hsl(var(--primary)/0.4);
  --red:hsl(var(--destructive));
  /* The deep, ALWAYS-DARK marketing-band / chrome surface (nav, hero, platform, assure,
     about, everywhere, pathways). It must stay dark in EVERY theme - unlike --background/
     --card which flip light in the light theme, and unlike --primary which goes pine-green
     in dark/brand. Default is the SUSE deep teal (= the old #0c322c); brand-vars.ts will
     override it per active brand in the app shell (M2) so a self-hosted org's dark bands
     carry their brand. Fixes the M1 bug where these bands used var(--dark) (=--foreground),
     which inverted to near-white text-on-band in dark mode. */
  --band-dark:171 62% 12%;
  /* The always-LIGHT ink that rides on --band-dark (headings, nav wordmark, nav/hero/
     platform/assure/everywhere/about/pathways copy). Paired with --band-dark so the
     always-dark chrome is fully brand-reactive: a self-hosted brand overrides BOTH the
     band surface and its on-dark ink. Defaults to white, so the neutral build renders
     byte-identical to the old hardcoded #fff. Crucially it is a dedicated token, NOT
     --primary-foreground: that one flips to BLACK under [data-a11y-contrast=high] in
     dark/brand, which would turn every band's white text black-on-dark. --on-band-dark
     stays light in every theme + contrast mode, so the a11y contract holds. */
  --on-band-dark:0 0% 100%;
  /* The always-BRIGHT accent that rides on --band-dark for CTAs on the dark chrome (the
     nav "Launch App" pill). Band-invariant like the pair above: the nav is dark in every
     theme, so its CTA must POP in every theme - it can't borrow --primary, which goes deep
     teal in the LIGHT theme and would sink the button into the dark band. Default is the
     pine green (= dark/brand --primary, the old bright SUSE green); brand-vars.ts overrides
     it per active brand in the app shell. Paired with --band-dark as its ink (dark-on-green,
     the original CTA look). */
  --band-accent:151 57% 46%;
  --orange:#fe7c3f;--navy:#192072;--blue:#2453ff;
  --col-cap:38rem;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{font-family:'SUSE',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:var(--text);background:var(--page);line-height:1.65}
a{color:var(--green);text-decoration:none}
a:hover{text-decoration:underline}
/* Safety net for inline icon SVGs: every one carries only a viewBox (no width/height),
   so without a scoped size rule it balloons to the CSS default 300×150 - or stretches to
   fill a flex/grid parent - and reads as an unfinished giant glyph. Default them to a
   text-sized square; sized contexts (.icon-*, .assure-card-ic, illustrations, …) override
   this with a more specific selector. Keeps a missing/renamed rule from ever ballooning. */
svg{width:1em;height:1em;flex:none}
code{font-family:'SUSE Mono','SF Mono','Fira Code',monospace;font-size:.875em;background:hsl(var(--muted));padding:.15em .35em;border-radius:3px}
pre{background:hsl(var(--muted));color:hsl(var(--foreground));padding:1.25rem 1.5rem;border-radius:8px;overflow-x:auto;white-space:pre-wrap;overflow-wrap:anywhere;font-size:.875rem;line-height:1.5;margin-bottom:1.25rem; box-shadow: inset 0 .2rem .4rem #0002, 0 1px #fff2}
pre code{background:none;padding:0;color:inherit;font-size:1em}
h1,h2,h3,h4{line-height:1.25;font-weight:700}
h2{font-size:2rem;letter-spacing:0;font-weight:900;text-transform:uppercase}
p{margin-bottom:2rem}
ul{padding-left:1.25rem;margin-bottom:1rem}
li{margin-bottom:.35rem}
blockquote{border-left:0; box-shadow:0 0 0 1px #30ba7825, inset 0 1px #fff3, inset 0 -1px #0001, 0 .1rem 2.4rem #30ba7855;  border-radius: 2em; padding: 1.5rem 2.25rem;background:var(--pale);margin:4rem 0;transform:scale(1.1)}
blockquote p{margin:0}
hr{border:none;border-top:1px solid var(--border);margin:2rem 0}
strong{font-weight:600}

/* Nav */
nav{display:flex;align-items:center;gap:.25rem;padding:0 1.5rem;height:3.75rem;background:transparent;position:fixed;width:100%;top:0;z-index:100;overflow-x:auto;transition:background .25s}
nav.nav-solid{background:hsl(var(--band-dark))}
/* On-page quick nav - a sticky jump bar under the top nav, on the landing only. */
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
section[id]{scroll-margin-top:6.4rem}
/* The nav sits on #0c322c in BOTH themes (nav.nav-solid, and the dark hero on the
   landing page), so its text needs a fixed light colour. It used var(--pale),
   which the dark theme redefines to #0d2419 - near-identical to that background,
   about 1.1:1, so the wordmark disappeared in dark mode. Every other nav control
   already uses a literal white for this reason. */
.brand{display:inline-flex;align-items:center;gap:.5rem;font-weight:800;color:hsl(var(--on-band-dark));font-size:1.05rem;white-space:nowrap;margin-right:.75rem;letter-spacing:-.01em;text-transform:uppercase}
.brand:hover{color:var(--light);text-decoration:none}
.brand-icon{width:1.5rem;height:1.5rem;border-radius:5px;flex-shrink:0;object-fit:contain}
/* Draft marker in the nav. English pages only (see buildNav) - the translated
   pages are a fallback to English source anyway, and a red pill nobody can read
   in their own language is a worse signal than none. flex:none so the scrolling
   nav can never squeeze it to unreadable. */
.nav-draft{display:inline-flex;align-items:center;flex:none;font-family:'SUSE Mono','SF Mono','Fira Code',monospace;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:hsl(var(--on-band-dark));background:var(--red);padding:.15em .6em;border-radius:999px;margin-right:.75rem;white-space:nowrap}
nav .gap{flex:1}
/* The <label> wrapping the icon + <select> is the WHOLE hit area - a generous
   pill, matching .nav-theme-toggle's footprint - not just the select's own tight
   text box. Clicking/tapping the icon activates the select exactly like clicking
   the text does (native label→control delegation), and since hover/focus is
   styled on the label, the icon (fill="currentColor") and the select text pick up
   the SAME colour change together via inheritance - no separate icon hover rule. */
.nav-lang-picker-wrap{display:inline-flex;align-items:center;gap:.4rem;padding:.45rem .75rem .45rem .6rem;border-radius:2em;color:hsl(var(--on-band-dark) / .55);cursor:pointer;transition:color .12s,background .12s}
.nav-lang-picker-wrap:hover,.nav-lang-picker-wrap:focus-within{color:hsl(var(--on-band-dark));background:rgba(255,255,255,.1)}
.nav-lang-picker-wrap .lang-switch-icon{width:16px;height:16px;flex-shrink:0;pointer-events:none}
.nav-lang-picker{background:transparent;color:inherit;border:none;font-size:.8125rem;cursor:pointer;padding:0}
.nav-lang-picker option{color:#000}
nav:not(.quicknav):not(.doc-jump-nav) a:not(.brand):not(.nav-launch){color:hsl(var(--on-band-dark) / .55);font-size:.8125rem;padding:.25rem .5rem;white-space:nowrap;border-radius:2em;transition:color .12s}
nav:not(.quicknav):not(.doc-jump-nav) a:not(.brand):not(.nav-launch):hover{color:hsl(var(--on-band-dark));text-decoration:none}
nav:not(.quicknav):not(.doc-jump-nav) a.active:not(.nav-launch){color:hsl(var(--on-band-dark))}
/* Top-nav clusters: tight within a group, a thin divider between groups. */
nav .nav-group{display:inline-flex;align-items:center;gap:.0625rem}
nav .nav-group + .nav-group{margin-left:.5rem;padding-left:.625rem;border-left:1px solid rgba(255,255,255,.18)}
.nav-launch{background:hsl(var(--band-accent));color:hsl(var(--band-dark))!important;padding:.375rem 1rem;border-radius:1.5em;font-weight:700;font-size:.875rem;white-space:nowrap;margin-left:.5rem;transition:background .15s}
.nav-launch:hover{background:hsl(var(--band-accent) / .82);text-decoration:none!important}

/* Language FAB menu - popup language selector matching the app UX */
.lang-fab-wrap{display:inline-flex}
.lang-fab{background:none;border:none;padding:.45rem .6rem;border-radius:2em;color:hsl(var(--on-band-dark) / .55);cursor:pointer;transition:color .12s,background .12s;width:32px;height:32px;display:flex;align-items:center;justify-content:center}
.lang-fab:hover{color:hsl(var(--on-band-dark));background:rgba(255,255,255,.1)}
.lang-fab svg{width:24px;height:24px}
.lang-menu{position:fixed;top:auto;right:1.5rem;margin-top:0;background:hsl(var(--band-dark) / .98);border:1px solid rgba(255,255,255,.15);border-radius:8px;min-width:200px;box-shadow:0 8px 32px rgba(0,0,0,.24);z-index:101;backdrop-filter:blur(8px)}
.lang-menu[hidden]{display:none}
.lang-sort-tabs{display:flex;gap:2px;margin:6px 6px 2px;padding:3px;background:rgba(255,255,255,.08);border-radius:999px}
.lang-sort-tab{flex:1 1 auto;white-space:nowrap;padding:4px 8px;border:0;cursor:pointer;background:transparent;color:hsl(var(--on-band-dark) / .55);font-family:'SUSE Mono','SF Mono','Fira Code',monospace;font-size:10.5px;letter-spacing:.04em;border-radius:999px;transition:background .12s,color .12s}
.lang-sort-tab:hover{color:hsl(var(--on-band-dark))}
.lang-sort-tab[aria-selected=true]{background:rgba(255,255,255,.16);color:hsl(var(--on-band-dark));font-weight:700;box-shadow:0 1px 2px rgba(0,0,0,.24)}
.lang-sort-tab:focus-visible{outline:2px solid var(--green);outline-offset:1px}
.lang-menu-list{display:flex;flex-direction:column;max-height:calc(100vh - 7.5rem);overflow-y:auto}
.lang-menu-item{background:none;border:none;display:flex;align-items:center;gap:.5rem;width:100%;padding:.625rem 1rem;color:hsl(var(--on-band-dark) / .7);text-align:left;cursor:pointer;transition:background .12s,color .12s;font-size:.8125rem;font-family:inherit}
.lang-menu-item:hover{background:rgba(255,255,255,.08);color:hsl(var(--on-band-dark))}
.lang-menu-item[aria-pressed=true]{background:rgba(48,186,120,.15);color:hsl(var(--on-band-dark))}
.lang-menu-flags{display:inline-flex;gap:.2em;min-width:4em;     place-content: flex-end;}
.lang-menu-name{flex:1}
.lang-sort-tab:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 1px; }
@media (min-width:800px){
.lang-menu-list {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    }
}

.quicknav{position:sticky;top:3.75rem;z-index:90;background:hsl(var(--background) / 0.9);border-bottom:1px solid var(--border);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
html[data-theme="dark"] .quicknav{background:rgba(9,26,21,.9)}
.quicknav-inner{max-width:1180px;margin:0 auto;display:flex;gap:.15rem;padding:0 1.5rem;overflow-x:auto;scrollbar-width:none}
.quicknav-inner::-webkit-scrollbar{display:none}
.quicknav a{flex:none;padding:.72rem .8rem;font-size:.82rem;font-weight:600;color:var(--muted);text-decoration:none;border-bottom:2px solid transparent;white-space:nowrap;transition:color .12s}
.quicknav a:hover{color:var(--green)}
.quicknav a.is-current{color:var(--green);border-bottom-color:var(--green)}
.section-more-row{text-align:center;margin-top:2rem}
.section-more{display:inline-flex;align-items:center;gap:.4em;font-size:.92rem;font-weight:700;color:var(--green);text-decoration:none}
.section-more:hover{text-decoration:underline}
.section-more span{transition:transform .15s}
.section-more:hover span{transform:translateX(3px)}
/* Hero */
/* Hero + pathways share one canvas backdrop: the animated chips drift up through
   both, and a single vertical gradient blends the hero green (#1c4a2e) into the
   pathways dark (--dark) so the two bands read as one continuous surface. */
.hero-wrap{position:relative;overflow:hidden;background:linear-gradient(180deg,#1c4a2e 0%,hsl(var(--band-dark)) 100%)}
.hero{background:transparent;color:hsl(var(--on-band-dark));padding:7rem 1.5rem 6rem;text-align:center;position:relative;z-index:1;min-height:50vh;user-select:none;-webkit-user-select:none}
/* Double-clicking the hero backdrop shouldn't highlight the heading/subtitle/trust copy; buttons keep normal selection. */
.hero .btn{user-select:auto;-webkit-user-select:auto}
.hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 90% 55% at 50% -5%,rgba(48,186,120,.13) 0%,transparent 65%);pointer-events:none}
#heroCanvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;mix-blend-mode:color-dodge;opacity:.6}
.hero h1{font-size:clamp(2.75rem,6vw,5rem);letter-spacing:-.04em;line-height:1.05;margin-bottom:1.5rem;color:hsl(var(--on-band-dark));position:relative;padding-left:.3em;font-weight:200}
/* The hero's headline statement - the page's single h1, above the pilot pill in the
   details column. Displayed in SUSE Mono, uppercased in CSS ONLY: the DOM text stays
   title case, so screen readers read it naturally and the non-Latin locales (whose
   scripts neither SUSE Mono nor text-transform:uppercase touch) fall back cleanly to a
   system face in normal case. The generic .hero h1 rule above still supplies its
   responsive text-align (start on desktop, centre on mobile), so this qualified rule
   (0,2,0) only sets the display treatment (and clears that rule's padding-left, written
   for the old logo h1). break-word + hyphens keep a long single-word translation (e.g.
   German Inhaltssouveränität) inside its column. */
.hero .hero-statement{font-family:'SUSE Mono','SF Mono','Fira Code',monospace;text-transform:uppercase;font-size:clamp(2.5rem,7vw,5.25rem);font-weight:100;letter-spacing:-.025em;max-width:90%; line-height:1.03;padding-left:0;margin:0 0 1.5rem;color:hsl(var(--on-band-dark));text-wrap:balance;overflow-wrap:break-word;hyphens:auto}
/* Radius + shadow live on the img itself - on the link they trace its layout box,
   which sits a hair off the rendered image edge and shows as a seam. */
/* The slot exists so the verify badge can position against the LOGO rather than
   against the full-width heading - without it a percentage offset resolves against
   the whole line and the badge lands out at the viewport edge. It carries the width
   the link used to own (the link now fills it). The logo is no longer the page's h1
   (that is the hero statement above now), so it is a plain mark; the badge stays a
   SIBLING of the logo link, not inside it, so "Verify this logo's credentials" is not
   folded into the logo link's accessible name. The reset just clears default box
   metrics on the mark. */
.hero-logo-slot{position:relative;width:clamp(180px,32vw,340px);margin:0 auto 1.5rem}
.hero .hero-logo-mark{margin:0;padding:0;line-height:0;position:relative}
.hero-logo-link{display:block;width:100%;border-radius:50%;cursor:pointer;transition:transform .2s ease}
.hero-logo-link:hover,.hero-logo-link:focus-visible{ outline:none}
.hero-logo-link:hover .hero-logo,.hero-logo-link:focus-visible .hero-logo{}
.hero-logo-link:active{transform:translateY(-1px) scale(1.0)}
.hero-logo{display:block;width:100%;height:auto;position:relative;border-radius:50%;    filter: hue-rotate(-15deg);transition:box-shadow .2s ease}
.hero-logo:hover{filter: hue-rotate(-25deg) saturate(1.5) brightness(1.01)}
/* The mark idles STILL until hover (Andy, 2026-08-17). The swirl animation lives
   INSIDE the signed icon.svg, which an <img> embeds as its own document - page CSS
   cannot pause it and the signed file is never edited. So the derived raster of the
   same mark (icon-512.png, from `npm run icons`) sits on top and lifts on hover/
   focus to let the swirl run. Under reduced motion - the OS preference or the app's
   a11y switch - the still never lifts. */
.hero-logo-link{position:relative}
.hero-logo-still{position:absolute;inset:0;width:100%;height:100%;border-radius:50%;filter:hue-rotate(-15deg);transition:opacity .25s ease;pointer-events:none}
.hero-logo-link:hover .hero-logo-still,.hero-logo-link:focus-visible .hero-logo-still{opacity:0}
@media (prefers-reduced-motion: reduce){
  .hero-logo-link:hover .hero-logo-still,.hero-logo-link:focus-visible .hero-logo-still{opacity:1}
}
html[data-a11y-motion="reduce"] .hero-logo-link:hover .hero-logo-still,
html[data-a11y-motion="reduce"] .hero-logo-link:focus-visible .hero-logo-still{opacity:1}
/* The verify badge. Sits ON the circle's lower-right diagonal (a circle inscribed in
   the slot meets that diagonal at 50%+35.4%), small enough that the mark is still the
   thing you see - the badge is an offer, not a second logo. Its own hit area is 44px
   at the smallest hero size, and it never grows past the point where it would read as
   part of the artwork. line-height on .hero-logo-mark is 0, hence the explicit box. */
.hero-verify{position:absolute;left:82%;top:82%;transform:translate(-50%,-50%);
  display:flex;align-items:center;justify-content:center;
  width:clamp(2.75rem,6vw,3.25rem);height:clamp(2.75rem,6vw,3.25rem);
  border-radius:50%;background:var(--green,#30ba78);color:hsl(var(--on-band-dark));
  box-shadow:0 .25em .6em #0005,0 0 0 .18em rgba(12,50,44,.55);
  transition:transform .2s ease,box-shadow .2s ease}
.hero-verify>span{display:flex;width:52%;height:52%}
.hero-verify svg{width:100%;height:100%;display:block}
.hero-verify:hover,.hero-verify:focus-visible{transform:translate(-50%,-50%) scale(1.08);
  box-shadow:0 .35em .8em #0006,0 0 0 .22em rgba(255,255,255,.75);outline:none}
@media(prefers-reduced-motion:reduce){.hero-verify{transition:none}
  .hero-verify:hover,.hero-verify:focus-visible{transform:translate(-50%,-50%)}}
.hero .subtitle{font-size:clamp(.9375rem,1.8vw,1.125rem);max-width:560px;margin:0 auto 2.75rem; margin-left:color:hsl(var(--on-band-dark) / .5);font-weight:300;line-height:1.85;position:relative}
.hero-cta{display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;position:relative;margin-bottom:2.5rem}
.hero-trust{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:.5rem;position:relative}
.hero-trust span{font-size:.8rem;line-height:1;color:hsl(var(--on-band-dark) / .5);letter-spacing:.02em}
.trust-dot{color:hsl(var(--on-band-dark) / .18)!important}
.btn{display:inline-flex;align-items:center;padding:2rem 3rem;border-radius:1rem;font-weight:700;font-size:1rem;transition:all .18s ease;box-shadow:0 .2em 1em #0002}
.btn-primary{background:rgba(48,186,120,.72);color:#000;mix-blend-mode:plus-lighter}
.btn-primary:hover{background:var(--light);text-decoration:none;transform:translateY(-2px);box-shadow:0 8px 28px rgba(48,186,120,.35)}
.btn-secondary{background:rgba(255,255,255,.05);color:hsl(var(--on-band-dark));border:1px solid rgba(255,255,255,.22);position:relative}
.btn-secondary:hover{background:rgba(255,255,255,.1);text-decoration:none;transform:translateY(-1px)}
/* Glass baseline - frosted blur so the buttons read as glass even where the JS
   liquid-displacement filter can't render. The buildGlass script overrides this
   inline with the refractive filter where it's supported. */
.btn-primary,.btn-secondary{-webkit-backdrop-filter:blur(3px) saturate(1.45);backdrop-filter:blur(3px) saturate(1.45)}

/* Three-door pathways band - sits directly under the hero on the landing page. */
.pathways-section{background:transparent;position:relative;z-index:1;padding:4rem 1.5rem}
.pathways-inner{max-width:1080px;margin:0 auto;text-align:center}
.pathways-head{display:flex;align-items:center;justify-content:center;gap:2.5rem;flex-wrap:wrap;margin:0 0 2.5rem;text-align:start}
.pathways-headtext{max-width:38rem}
.pathways-title{color:hsl(var(--on-band-dark));font-size:2rem;margin:0 0 .5rem}
.pathways-mascot{width:clamp(160px,20vw,300px);flex-shrink:0}
.pathways-lead{color:hsl(var(--on-band-dark) / .7);font-size:1.0625rem;margin:0}
.pathways-lead a{color:var(--light);font-weight:600}
.pathways-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1.25rem;text-align:start}
@media(max-width:1020px){.pathways-grid{grid-template-columns:repeat(2,1fr)}}
.pathway-card{    backdrop-filter: blur(5px);display:flex;flex-direction:column;gap:.5rem;padding:1.75rem;border-radius:14px;background:rgba(255,255,255,.05);border:0;    box-shadow: inset 0 1px #fff1, 0 .2em .5em #0002;transition:transform .18s ease,border-color .18s ease,background .18s ease}
.pathway-card:hover{text-decoration:none;transform:translateY(-3px);border-color:var(--green);background:rgba(255,255,255,.08)}
.pathway-ic{align-self:flex-start;display:inline-flex;align-items:center;justify-content:center;width:2.75rem;height:2.75rem;margin-bottom:.35rem;border-radius:12px;color:hsl(var(--on-band-dark));background:linear-gradient(163deg,hsl(150 66% 51%),hsl(154 58% 33%));border:1px solid hsl(0 0% 100% / .3);box-shadow:inset 0 1px 0 hsl(0 0% 100% / .45),0 6px 16px -6px hsl(151 57% 40% / .75);transition:box-shadow .18s ease,transform .18s ease}
.pathway-ic svg{width:1.45rem;height:1.45rem}
.pathway-card:hover .pathway-ic{transform:translateY(-1px);box-shadow:inset 0 1px 0 hsl(0 0% 100% / .5),0 9px 22px -6px hsl(151 57% 40% / .9)}
.pathway-eyebrow{font-size:.75rem;text-transform:uppercase;letter-spacing:.1em;font-weight:700;color:hsl(var(--on-band-dark));}
.pathway-name{font-size:1.375rem;font-weight:200;color:var(--green)}
.pathway-desc{font-size:.9375rem;line-height:1.55;color:hsl(var(--on-band-dark) / .68);flex:1}
.pathway-go{font-size:.9375rem;font-weight:600;color:var(--light);margin-top:.5rem}
@media(max-width:820px){.pathways-grid{grid-template-columns:1fr}}

/* Audience section */
.audience-section{}
.audience-header{background:linear-gradient(180deg,var(--pale) 0%,#fff 100%)}
.audience-title{font-size:2.5rem;color:var(--dark);margin:0}
.audience-sub{color:var(--muted);font-size:.9375rem;margin-top:.5rem;margin-bottom:0}
/* CSS-only tabs (plan 123 D1 final form). The radios are visually hidden but stay
   focusable - the native radio group IS the keyboard interface, and the focus ring is
   painted onto the paired pill below. Never display:none them. */
.aud-radio{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.audience-tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem;padding:.875rem 1.5rem 1.25rem;background:hsl(var(--background));border-bottom:2px solid var(--border);max-width:1400px;margin:0 auto}
.audience-tab{display:inline-flex;align-items:center;gap:.45rem;padding:.5rem .95rem;border:2px solid var(--border);background:hsl(var(--card));cursor:pointer;border-radius:999px;color:var(--muted);transition:all .15s;font-family:'SUSE',inherit}
.audience-tab .tab-icon{width:1.05rem;height:1.05rem}
.audience-tab .tab-icon svg{width:100%;height:100%}
.audience-tab .tab-label{font-size:.62rem;font-weight:700;text-transform:uppercase;letter-spacing:.09em;white-space:nowrap}
.audience-tab:hover{border-color:var(--green);color:var(--dark);background:var(--pale)}

/* Audience panels. Layout and visibility are kept apart on purpose: the card's layout
   lives in the base rule (and flips to a flex column in the phone media block via
   --aud-card-display), while visibility is the radio pairing below - so the mobile
   override never has to out-specify the show rule. The machines band's cards are never
   gated: the hide rule anchors on a preceding .aud-radio sibling, which only the
   tabbed section has. */
.audience-panels{display:block;margin-bottom:2em}
.audience-card{
  --aud-card-display:grid;
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);
  gap:2.5rem 5rem;
  align-items:start;
  padding:3.75rem 3.5rem;
  max-width:1400px;
  margin:0 auto;
  scroll-margin-top:5rem;
}
.aud-radio ~ .audience-panels > .audience-card{display:none}
/* An old #slug deep link opens its card without any radio involvement. */
.aud-radio ~ .audience-panels > .audience-card:target{display:var(--aud-card-display,grid)}
/* Index-matched pairing: radio N shows card N, styles pill N. Nine slots so a new
   audience section never silently falls off the end (seven are in use today). */
.aud-radio:nth-of-type(1):checked ~ .audience-panels > .audience-card:nth-child(1),
.aud-radio:nth-of-type(2):checked ~ .audience-panels > .audience-card:nth-child(2),
.aud-radio:nth-of-type(3):checked ~ .audience-panels > .audience-card:nth-child(3),
.aud-radio:nth-of-type(4):checked ~ .audience-panels > .audience-card:nth-child(4),
.aud-radio:nth-of-type(5):checked ~ .audience-panels > .audience-card:nth-child(5),
.aud-radio:nth-of-type(6):checked ~ .audience-panels > .audience-card:nth-child(6),
.aud-radio:nth-of-type(7):checked ~ .audience-panels > .audience-card:nth-child(7),
.aud-radio:nth-of-type(8):checked ~ .audience-panels > .audience-card:nth-child(8),
.aud-radio:nth-of-type(9):checked ~ .audience-panels > .audience-card:nth-child(9){display:var(--aud-card-display,grid)}
.aud-radio:nth-of-type(1):checked ~ .audience-tabs > .audience-tab:nth-child(1),
.aud-radio:nth-of-type(2):checked ~ .audience-tabs > .audience-tab:nth-child(2),
.aud-radio:nth-of-type(3):checked ~ .audience-tabs > .audience-tab:nth-child(3),
.aud-radio:nth-of-type(4):checked ~ .audience-tabs > .audience-tab:nth-child(4),
.aud-radio:nth-of-type(5):checked ~ .audience-tabs > .audience-tab:nth-child(5),
.aud-radio:nth-of-type(6):checked ~ .audience-tabs > .audience-tab:nth-child(6),
.aud-radio:nth-of-type(7):checked ~ .audience-tabs > .audience-tab:nth-child(7),
.aud-radio:nth-of-type(8):checked ~ .audience-tabs > .audience-tab:nth-child(8),
.aud-radio:nth-of-type(9):checked ~ .audience-tabs > .audience-tab:nth-child(9){background:hsl(var(--band-dark));color:hsl(var(--on-band-dark));border-color:hsl(var(--band-dark));box-shadow:0 3px 12px rgba(12,50,44,.2)}
.aud-radio:nth-of-type(1):focus-visible ~ .audience-tabs > .audience-tab:nth-child(1),
.aud-radio:nth-of-type(2):focus-visible ~ .audience-tabs > .audience-tab:nth-child(2),
.aud-radio:nth-of-type(3):focus-visible ~ .audience-tabs > .audience-tab:nth-child(3),
.aud-radio:nth-of-type(4):focus-visible ~ .audience-tabs > .audience-tab:nth-child(4),
.aud-radio:nth-of-type(5):focus-visible ~ .audience-tabs > .audience-tab:nth-child(5),
.aud-radio:nth-of-type(6):focus-visible ~ .audience-tabs > .audience-tab:nth-child(6),
.aud-radio:nth-of-type(7):focus-visible ~ .audience-tabs > .audience-tab:nth-child(7),
.aud-radio:nth-of-type(8):focus-visible ~ .audience-tabs > .audience-tab:nth-child(8),
.aud-radio:nth-of-type(9):focus-visible ~ .audience-tabs > .audience-tab:nth-child(9){outline:2px solid var(--green);outline-offset:2px}
.card-main{min-width:0;overflow:hidden}
.card-icon{width:2.5rem;height:2.5rem;color:var(--green);margin-bottom:1.25rem}
.card-icon svg{width:100%;height:100%}
.card-audience{font-size:.6875rem;text-transform:uppercase;letter-spacing:.14em;color:var(--green);font-weight:700;margin-bottom:.375rem}
.card-tagline{font-size:1.5rem;font-weight:800;color:var(--dark);margin-bottom:.75rem;line-height:1.2;letter-spacing:-.02em}
.card-intro{font-size:.9375rem;color:var(--muted);line-height:1.75;margin-bottom:1.5rem}
.card-main pre{font-size:.8rem;margin-top:0;margin-bottom:0;white-space:pre-wrap;overflow-wrap:anywhere;box-sizing:border-box}
.card-main pre::-webkit-scrollbar{display:none}
.card-benefits{display:grid;grid-template-columns:1fr 1fr;gap:4em;padding-left:0;list-style:none;margin:0;padding-top:.25rem}
.card-benefits li{display:flex;align-items:flex-start;gap:.75rem;font-size:.9375rem;line-height:1.6;color:var(--text)}
.card-benefits li:last-child{margin-bottom:0}
.bullet-icon{width:3em;height:3em;display:block;margin:1em 0;color:var(--green);flex-shrink:0}
.bullet-icon svg{width:100%;height:100%}
.card-benefits strong{font-weight:700;color:var(--dark)}

/* Platform + What's a tool - side by side on desktop */
.platform-whats-wrap{position:relative;display:flex;align-items:stretch}
/* The try-now callout straddles this wrap's bottom seam (absolute, translateY 50%), so
   BOTH sides of the seam reserve room for its halves: the columns carry enough bottom
   padding that the top half never covers their last lines, and the teaser that follows
   the wrap clears the bottom half the same way. Copy growth eats headroom, not text. */
.platform-whats-wrap .platform-section,.platform-whats-wrap .whats-a-tool{flex:1;min-width:0;padding-bottom:8rem}
.platform-whats-wrap+.teaser-section{padding-top:7.5rem}
/* The floating section eyebrow at the band junction. The band-dark PAIR, not loose
   tokens: the previous background:var(--muted) was a FOREGROUND ink used as a ground,
   with a surface token as its text - two mid-tones in every theme. The pair is
   theme-stable, brand-reactive, and matches the selected tab pills. */
.whats-label{position:absolute;top:0;left:50%;transform:translate(-50%,-50%);z-index:10;border-radius:3rem;padding:.85rem 2rem;font-weight:700;font-size:1.0625rem;white-space:nowrap;box-shadow:0 6px 20px rgba(0,0,0,.18);background:hsl(var(--band-dark));color:hsl(var(--on-band-dark))}

/* Platform */
.platform-section{background:linear-gradient(20deg,#0c322c 0%,#008657 100%);color:hsl(var(--on-band-dark));padding:4.5rem 3.5rem}
.platform-inner{max-width:var(--col-cap);margin-left:auto;margin-right:0}
.platform-header{text-align:center;margin-bottom:2.75rem}
.platform-section h2{margin-bottom:.5rem}
.platform-tagline{color:hsl(var(--on-band-dark) / .8);font-size:1.0625rem;margin:0;letter-spacing:.01em}
.platform-features{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.08);border-radius:14px;overflow:hidden;margin-bottom:1.75rem}
.platform-feature{background:rgba(255,255,255,.025);padding:1.625rem 1.5rem;display:flex;flex-direction:column;gap:.5rem;transition:background .15s}
.platform-feature:hover{background:#00000033}
.platform-feature-icon{width:1.75rem;height:1.75rem;color:var(--green);margin-bottom:.375rem}
.platform-feature-icon svg{width:100%;height:100%}
.platform-feature strong{font-size:.9375rem;font-weight:700;line-height:1.3}
.platform-feature p{color:hsl(var(--on-band-dark) / .45);font-size:.85rem;margin:0;line-height:1.6}
.platform-feature:last-child:nth-child(odd){grid-column:1 / -1}
.rt-mark{font-family:'SUSE',sans-serif;font-weight:700;letter-spacing:0;margin-right:.32em;line-height:1}
.rt-inline{color:var(--green);font-weight:600;white-space:nowrap}
.rt-inline .rt-mark{margin-right:.1em}
/* ── Block 2: make something, right now (plan 117) ──────────────────────────
   Three worked examples, each a plain link into the app carrying the example's
   own inputs. The picture is the tool's own preview of that exact look, so the
   card cannot promise a look the click does not deliver. Cards are <a>, so the
   whole tile is the hit area and keyboard focus lands on it once. */
.make-section{background:hsl(var(--background));padding:5rem 1.5rem}
.make-inner{max-width:1180px;margin:0 auto}
.make-head{max-width:44rem;margin:0 auto 2.5rem;text-align:center}
.make-head h2{color:var(--dark);margin:0 0 .75rem}
html[data-theme="dark"] .make-head h2{color:hsl(var(--foreground))}
.make-lead{color:var(--muted);font-size:1.05rem;line-height:1.7;margin:0}
.make-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem}
@media(max-width:900px){.make-grid{grid-template-columns:1fr;max-width:26rem;margin:0 auto}}
.make-card{display:flex;flex-direction:column;background:hsl(var(--card));border:1px solid var(--border);border-radius:16px;padding:1rem 1rem 1.15rem;color:inherit;text-decoration:none;transition:transform .15s,box-shadow .15s,border-color .15s}
.make-card:hover,.make-card:focus-visible{transform:translateY(-3px);box-shadow:0 .8rem 2rem rgba(12,50,44,.13);border-color:var(--green);text-decoration:none}
.make-card:focus-visible{outline:2px solid var(--green);outline-offset:3px}
.make-shot{display:block;background:var(--pale);border-radius:11px;overflow:hidden;aspect-ratio:4/3;margin-bottom:.95rem}
.make-shot img{width:100%;height:100%;object-fit:contain;display:block}
.make-scene{font-size:1.0625rem;font-weight:700;color:var(--dark);line-height:1.3}
html[data-theme="dark"] .make-scene{color:hsl(var(--foreground))}
.make-line{color:var(--muted);font-size:.9rem;line-height:1.6;margin-top:.35rem;flex:1}
.make-go{margin-top:.9rem;font-size:.875rem;font-weight:700;color:var(--green);display:inline-flex;align-items:center;gap:.4em}
.make-card:hover .make-go span{transform:translateX(3px)}
.make-go span{transition:transform .15s}

/* ── Block 3: the sovereignty statement ─────────────────────────────────────
   The one full statement of internet-optionality on the page, and deliberately
   the quietest band on it: no cards, no icons, no illustration - one paragraph
   on the always-dark chrome surface, with two receipt links under it. */
.sovereign-section{background:hsl(var(--band-dark));color:hsl(var(--on-band-dark));padding:5.5rem 1.5rem}
.sovereign-inner{max-width:52rem;margin:0 auto;text-align:center}
.sovereign-statement{font-size:clamp(.9rem,2.2vw,1rem);line-height:1.75;margin:0;color:hsl(var(--on-band-dark) / .78);text-wrap:pretty}
.sovereign-statement strong{color:hsl(var(--on-band-dark));font-weight:700}
.sovereign-receipts{margin-top:2rem;display:flex;align-items:center;justify-content:center;gap:.75rem;font-size:.875rem}
.sovereign-receipts a{color:hsl(var(--on-band-dark) / .62);text-decoration:underline;text-underline-offset:.25em}
.sovereign-receipts a:hover{color:hsl(var(--on-band-dark))}
.sovereign-dot{color:hsl(var(--on-band-dark) / .35)}

/* ── Block 5: AI, on your terms ─────────────────────────────────────────────
   Three short answers, no illustration: this block exists to remove worry, and
   a decorated one would read as a pitch. */
.ai-section{background:hsl(var(--background));padding:5rem 1.5rem;border-top:1px solid var(--border)}
.ai-inner{max-width:1000px;margin:0 auto}
.ai-head{max-width:42rem;margin:0 auto 2.5rem;text-align:center}
.ai-head h2{color:var(--dark);margin:0 0 .75rem}
html[data-theme="dark"] .ai-head h2{color:hsl(var(--foreground))}
.ai-lead{color:var(--muted);font-size:1.05rem;line-height:1.7;margin:0}
.ai-points{display:grid;grid-template-columns:repeat(3,1fr);gap:1.75rem}
@media(max-width:820px){.ai-points{grid-template-columns:1fr;max-width:30rem;margin:0 auto}}
.ai-point strong{display:block;font-size:1rem;color:var(--dark);margin-bottom:.4rem}
html[data-theme="dark"] .ai-point strong{color:hsl(var(--foreground))}
.ai-point p{color:var(--muted);font-size:.9375rem;line-height:1.7;margin:0}

/* ── Block 7: who is behind this, and why ───────────────────────────────────
   The progressive-disclosure turn, low on the page and once. One paragraph in a
   narrow measure - the only place on the landing where "we" is the subject. */
.behind-section{background:var(--pale);padding:4.5rem 1.5rem}
.behind-inner{max-width:66rem;margin:0 auto;text-align:start}
/* Two columns, left-aligned (Andy, 2026-08-17): the sceptic paragraph and the assurance
   side by side, with the founded-by badge anchoring the foot row once. */
.behind-cols{display:grid;grid-template-columns:1fr 1fr;gap:2rem 3.5rem;align-items:start}
.behind-foot{display:flex;align-items:center;justify-content:space-between;gap:1.5rem;flex-wrap:wrap;margin-top:2.5rem}
/* Moved here from build.ts (2026-08-17) so the reader gets it too: founded-by.svg is
   viewBox-only (no intrinsic width), and without the explicit width the inline anchor
   and the intrinsically-unsized image collapse to 0x0 together - which is exactly what
   happened in-app while these rules lived only in the static blob. */
.founded-badge{display:inline-block;line-height:0}
.founded-badge img{display:block;width:15em;max-width:100%;height:auto}
.behind-foot .behind-links{margin-top:0;justify-content:flex-start}
@media(max-width:800px){.behind-cols{grid-template-columns:1fr}}
.behind-eyebrow{display:inline-block;font-size:.6875rem;text-transform:uppercase;letter-spacing:.14em;font-weight:700;color:var(--green);margin-bottom:1.1rem}
.behind-para{font-size:1.0625rem;line-height:1.85;color:var(--muted);margin:0}
.behind-para strong{color:var(--dark);font-weight:700}
html[data-theme="dark"] .behind-para strong{color:hsl(var(--foreground))}
.behind-assure{margin-top:0}
/* The refusal band (plan 122 block 11): the trio + the visible vote, reusing the
   tool-feature card grid so the beats read as one set. */
.refusal-section{padding:4.5rem 1.5rem;background:var(--page)}
.refusal-section .assure-inner{max-width:1080px;margin:0 auto}
.refusal-title{text-align:center;font-size:1.75rem;margin:0 0 2rem}
.refusal-beats{margin-top:0}
/* The quokka rides beside the 2x2 beats, at ease - a calm mascot for a section
   that promises nothing is taken. Beats flex-grow; the mascot holds its width. */
.refusal-row{display:flex;align-items:center;justify-content:center;gap:2.25rem}
.refusal-row .refusal-beats{flex:1 1 auto;min-width:0;margin-bottom:0}
.refusal-mascot{width:clamp(160px,22vw,320px);flex-shrink:0;filter:drop-shadow(0 14px 34px rgba(0,0,0,.4))}
@media(max-width:820px){.refusal-row{flex-direction:column;gap:1.75rem}.refusal-mascot{width:min(52vw,240px)}}
/* The machines band sits directly under the human tabs: two sections, two
   deliberately CONTRASTING treatments (plan 123). The agents card is a deep split
   panel - the prompt is the hero, framed as a terminal pane - and the security card
   is a light ruled audit sheet, one claim per row. Both escape the audience radio
   gating entirely (no .audience-card class). */
.machines-section{padding-top:0}
.machines-band{max-width:1400px;margin:0 auto 2.5rem;padding:0 3.5rem;display:flex;flex-direction:column;gap:2rem}
.machine-card{border-radius:16px;scroll-margin-top:5rem}
.mc-eyebrow{display:inline-flex;align-items:center;gap:.5rem;font-size:.6875rem;text-transform:uppercase;letter-spacing:.14em;font-weight:700;color:var(--green)}
.mc-ic{display:inline-flex}
.mc-ic svg{width:1.25rem;height:1.25rem}
.machine-card .bullet-icon{flex:none;color:var(--green)}
.machine-card .bullet-icon svg{width:1.25rem;height:1.25rem}
.mc-title{font-size:1.5rem;font-weight:800;letter-spacing:-.02em;margin:.5rem 0 .75rem;line-height:1.2;text-transform:none}
.mc-intro{font-size:.9375rem;line-height:1.65;margin:0 0 1.25rem;max-width:56ch}

.machine-card--agents{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:2.5rem;align-items:center;background:hsl(var(--band-dark));color:hsl(var(--on-band-dark));padding:2.75rem 3rem}
/* On the deep band, var(--green) is the LIGHT theme's dark teal - invisible ink here.
   The band-accent pair is the theme-stable bright accent made for this ground. */
.machine-card--agents .mc-eyebrow,
.machine-card--agents .bullet-icon,
.machine-card--agents .mc-points a{color:hsl(var(--band-accent))}
.machine-card--agents .mc-title{color:hsl(var(--on-band-dark))}
.machine-card--agents .mc-intro{color:hsl(var(--on-band-dark)/.75)}
.machine-card--agents .mc-points{list-style:none;padding:0;margin:0;display:grid;grid-template-columns:1fr 1fr;gap:.9rem 1.5rem}
.machine-card--agents .mc-points li{display:flex;gap:.6rem;font-size:.8125rem;line-height:1.55;color:hsl(var(--on-band-dark)/.82)}
.machine-card--agents .mc-points strong{color:hsl(var(--on-band-dark))}
.machine-card--agents .mc-points a{color:var(--green)}
.machine-card--agents .mc-term{background:#071512;border:1px solid hsl(0 0% 100%/.08);border-radius:12px;overflow:hidden;box-shadow:0 14px 40px -18px rgba(0,0,0,.6)}
.machine-card--agents .mc-term pre{margin:0;background:none;box-shadow:none;padding:1.25rem 1.4rem;font-size:.8125rem;line-height:1.7;color:#7fe7b4;white-space:pre-wrap}
.machine-card--agents .mc-term pre code{background:none;color:inherit}

.machine-card--audit{background:hsl(var(--card));border:1px solid var(--border);padding:2.75rem 3rem}
.machine-card--audit .mc-title{color:var(--dark)}
.machine-card--audit .mc-intro{color:var(--muted);margin-bottom:0}
.machine-card--audit .mc-audit{list-style:none;margin:1.75rem 0 0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:0 3rem}
.machine-card--audit .mc-audit li{display:flex;gap:.75rem;padding:1rem 0;border-top:1px solid var(--border);font-size:.875rem;line-height:1.6;color:var(--muted)}
.machine-card--audit .mc-audit strong{color:var(--dark)}

@media(max-width:900px){
  .machines-band{padding:0 1.25rem}
  .machine-card--agents{grid-template-columns:minmax(0,1fr);padding:2rem 1.5rem}
  .machine-card--audit{padding:2rem 1.5rem}
  .machine-card--audit .mc-audit{grid-template-columns:1fr}
  .machine-card--agents .mc-points{grid-template-columns:1fr}
}
.machines-title{font-size:clamp(1.5rem,2.6vw,2.25rem)!important;-webkit-text-stroke:0;letter-spacing:0}
.assure-status{font-size:.9375rem; max-width:64ch;margin:1.5rem auto 0;text-align:center}
/* Dark-band contrast repairs (2026-08-16 review): these elements inherit the deep
   green --dark ink while sitting ON a deep green band, which reads as empty boxes.
   Explicit paint, appended last so it wins the cascade. */
.matrix-head--new{color:#fff}
.pathway-name{color:#fff}
.pathways-section .pathway-card .pathway-go{color:#30ba78;opacity:1}
.pathways-section .pathway-card:hover .pathway-go{color:#fff}
.everywhere-section .section-more{color:#fff;text-decoration:underline;text-underline-offset:3px}
.platform-feature a{color:#fff;text-decoration:underline;text-underline-offset:2px}
.behind-links{margin-top:1.6rem;display:flex;align-items:center;justify-content:center;gap:.75rem;font-size:.875rem;font-weight:600}
.behind-dot{color:var(--muted);opacity:.5}

/* ── Block 9: the teaser a moved band leaves behind ─────────────────────────
   One line and one link. The reference content itself lives on its own page,
   with the layout that made it readable (formatsSection / importBand). */
.teaser-section{background:hsl(var(--background));padding:3rem 1.5rem;border-top:1px solid var(--border)}
.teaser-inner{max-width:46rem;margin:0 auto;text-align:center}
.teaser-line{font-size:1.05rem;line-height:1.7;color:var(--muted);margin:0 0 .6rem}

/* The two moved bands, rendering inside a docs article column rather than
   full-bleed on the landing: drop the band padding the column already supplies,
   and let the import band sit flush under the masthead as the page's opener. */
.docs-content .import-section{background:none;padding:0 0 2.5rem;margin-bottom:2.5rem;border-bottom:1px solid var(--border)}
.docs-content .import-section h2{border-top:none;padding-top:0;margin-top:0}
.docs-content .import-inner{max-width:none}
.docs-content .import-lede{margin-bottom:2rem}
.page-formats .formats-section{padding:2.5rem 0 0;border-top:none;background:none}
.page-formats .formats-inner{max-width:none}
.page-formats .formats-head{margin-bottom:1.25rem}

/* Formats - ONE three-zone table: import-only (left) · round-trip (centre) · export-only (right) */
.formats-section{background:hsl(var(--background));padding:5.5rem 2rem;border-top:1px solid var(--border)}
html[data-theme="dark"] .formats-section{background:hsl(var(--background));border-top-color:hsl(var(--border))}
.formats-inner{max-width:1340px;margin:0 auto}
.formats-head{margin-bottom:2rem}
.formats-head h2{color:var(--dark);font-size:2rem;margin:0 0 .6rem}
html[data-theme="dark"] .formats-head h2{color:hsl(var(--foreground))}
.formats-head p{color:var(--muted);font-size:1.05rem;line-height:1.65;margin:0;max-width:44rem}
.formats-hint{font-size:.9rem;margin-top:.7rem !important;color:var(--green) !important;font-weight:600}
.fmt-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
/* Grid with a FIXED centre and flexible sides: 'both' is an auto track (never wraps,
   sits at the true row centre); import / export are 1fr and wrap only when full. Given
   the wide .formats-inner below, that keeps most rows on one line while guaranteeing the
   round-trip set is never broken across lines. Hard start / centre / end aligned. */
.fmt-table{display:grid;grid-template-columns:[cat]minmax(3.5rem,auto)[in]1fr[both]auto[out]1fr;align-items:center;column-gap:1.25rem;row-gap:.55rem;min-width:660px;padding-bottom:.5rem}
.fmt-row{display:contents}
.fmt-cat{grid-column:cat;display:flex;flex-direction:column;align-items:flex-start;gap:.35rem}
.fmt-cat svg{width:27px;height:27px;color:var(--green);opacity:.9}
.fmt-cat-label{font-size:.64rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);white-space:nowrap}
.fmt-zone{display:flex;flex-wrap:wrap;gap:.4rem;align-content:center;min-width:0}
.fmt-zone--in{grid-column:in;justify-content:flex-start}
.fmt-zone--both{grid-column:both;justify-content:center}
.fmt-zone--out{grid-column:out;justify-content:flex-end}
.fmt-zonelabel{font-size:.6rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);display:inline-flex;align-items:center;gap:.45em;white-space:nowrap}
.fmt-zonelabel .rt-mark{margin:0;color:var(--green)}
.fmt-zonelabel b{color:var(--green);background:rgba(48,186,120,.12);padding:.15em .5em;border-radius:1em;font-family:'SUSE Mono','SF Mono',monospace;font-size:.92em;font-weight:700}
.fmt-divider{grid-column:1/-1;height:0;border-bottom:2px solid var(--border);margin:.15rem 0 .35rem}
.fmt-rowsep{grid-column:1/-1;height:0;border-top:1px solid var(--border);margin:.15rem 0}
.fmt-chip{display:inline-flex;align-items:center;background:rgba(48,186,120,.1);color:#127a45;font-size:.74rem;font-family:'SUSE Mono','SF Mono',monospace;font-weight:700;padding:.3em .64em;border-radius:1em;letter-spacing:.03em;border:1px solid transparent;cursor:pointer;transition:transform .1s,box-shadow .12s,background .12s,color .12s;white-space:nowrap;-webkit-appearance:none;appearance:none}
.fmt-chip:hover{transform:translateY(-1px);box-shadow:0 3px 10px rgba(12,50,44,.16)}
.fmt-chip:focus-visible{outline:2px solid var(--green);outline-offset:2px}
.fmt-chip--both{background:var(--green);color:hsl(var(--on-band-dark))}
.fmt-chip .rt-mark{margin-right:.3em}
html[data-theme="dark"] .fmt-chip,html[data-theme="brand"] .fmt-chip{background:rgba(48,186,120,.16);color:#7fe7b4}
html[data-theme="dark"] .fmt-chip--both,html[data-theme="brand"] .fmt-chip--both{background:var(--green);color:#04140c}
/* Educational dialog */
.fmt-dialog{border:0;border-radius:18px;padding:0;width:min(94vw,38rem);max-height:88vh;overflow:auto;margin:auto;color:var(--dark);background:hsl(var(--popover));box-shadow:0 30px 80px rgba(12,50,44,.34)}
.fmt-dialog::backdrop{background:rgba(8,20,15,.5);backdrop-filter:blur(3px)}
html[data-theme="dark"] .fmt-dialog{background:hsl(var(--popover));color:hsl(var(--foreground))}
.fmt-dialog-inner{padding:1.75rem 1.75rem 1.6rem;position:relative}
.fmt-dialog-x{position:absolute;top:.7rem;right:.7rem;border:0;background:var(--pale);width:1.9rem;height:1.9rem;border-radius:50%;cursor:pointer;color:var(--muted);font-size:.82rem;line-height:1}
.fmt-dialog-x:hover{background:var(--border)}
.fmt-dialog-dir{display:inline-block;font-size:.62rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--green);background:rgba(48,186,120,.14);padding:.3em .7em;border-radius:1em;margin-bottom:.7rem}
.fmt-dialog h3{margin:0;color:inherit;font-size:1.55rem;line-height:1.1}
.fmt-dialog-head{display:flex;align-items:flex-start;gap:.9rem;padding-right:1.8rem}
.fmt-dialog-icon{flex:none;place-self:end;width:2.9rem;height:2.9rem;color:var(--green);margin-top:.1rem}
.fmt-dialog-icon svg{stroke-width:.5px;width:100%;height:100%;display:block}
.fmt-dialog-icon:empty{display:none}
.fmt-dialog-headtext{min-width:0}
.fmt-dialog-full{margin:.15rem 0 0;color:var(--muted);font-size:.9rem;font-weight:600}
.fmt-dialog-desc{margin:.9rem 0 0;color:inherit;font-size:.95rem;line-height:1.65;opacity:.92}
.fmt-dialog-specs{list-style:none;margin:1.1rem 0 0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:.45rem .9rem}
.fmt-dialog-specs:empty{margin:0}
.fmt-dialog-specs li{font-size:.82rem;line-height:1.3;color:inherit;display:flex;align-items:flex-start;gap:.45em;opacity:.95}
.fmt-dialog-specs li::before{content:'✓';color:var(--green);font-weight:800;flex:none;margin-top:.02em}
@media(max-width:520px){.fmt-dialog-specs{grid-template-columns:1fr}}
.fmt-dialog-feats{list-style:none;margin:1.15rem 0 0;padding:0;display:flex;flex-wrap:wrap;gap:.4rem}
.fmt-dialog-feats:empty{margin:0}
.fmt-dialog-feats li{font-size:.72rem;font-weight:700;color:inherit;background:var(--pale);border:1px solid var(--border);padding:.32em .68em;border-radius:1em;display:inline-flex;align-items:center;gap:.4em}
.fmt-dialog-feats li::before{content:'';width:.5em;height:.5em;border-radius:50%;background:var(--green);flex:none}
/* The format's metadata claims (plans/144 O1): what Lolly reads and writes in
   its own metadata containers, and what survives a round trip. Empty when a row
   carries no block, so the margin collapses with it. */
.fmt-dialog-meta{margin:1.1rem 0 0;font-size:.78rem;line-height:1.55;color:inherit;opacity:.8}
.fmt-dialog-meta:empty{margin:0}
.fmt-dialog-unsup{margin:1.2rem 0 0;padding:.85rem 1rem;border-radius:12px;background:rgba(254,124,63,.1)}
.fmt-dialog-unsup[hidden]{display:none}
.fmt-dialog-unsup-label{display:block;font-size:.62rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--orange);margin-bottom:.5rem}
.fmt-dialog-unsup-list{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:.4rem .9rem}
.fmt-dialog-unsup-list li{font-size:.82rem;line-height:1.3;display:flex;align-items:flex-start;gap:.45em;opacity:.9}
.fmt-dialog-unsup-list li::before{content:'-';color:var(--orange);font-weight:800;flex:none}
@media(max-width:520px){.fmt-dialog-unsup-list{grid-template-columns:1fr}}
html[data-theme="dark"] .fmt-dialog-unsup{background:rgba(254,124,63,.13)}
@media(max-width:760px){
.formats-section{padding:4rem 1.25rem}
.fmt-table{min-width:0;display:block}
.fmt-row{display:block;padding:.6rem 0;border-bottom:1px solid var(--border)}
.fmt-row--head{display:none}
.fmt-divider,.fmt-rowsep{display:none}
.fmt-cat{flex-direction:row;align-items:center;gap:.5rem;margin-bottom:.5rem}
.fmt-cat svg{width:20px;height:20px}
.fmt-zone{justify-content:flex-start!important;margin:.2rem 0}
.fmt-zone:empty{display:none}
.fmt-zone:not(:empty)::before{flex-basis:100%;font-size:.56rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-bottom:.15rem}
.fmt-zone--in:not(:empty)::before{content:'Import only'}
.fmt-zone--both:not(:empty)::before{content:'⇄ Both ways'}
.fmt-zone--out:not(:empty)::before{content:'Export only'}
}

/* QoL pair - sound + bulk, side by side */
.qol-section{background:var(--pale);padding:5.5rem 2rem}
.qol-inner{max-width:2480px;margin:0 auto;display:grid;grid-template-columns:1fr 1fr 1fr 1fr 1fr;gap:1rem}
.qol-panel{background:hsl(var(--card));border:1px solid var(--border);border-radius:20px;padding:2rem  1rem;box-shadow:0 4px 20px rgba(12,50,44,.06);display:flex;flex-direction:column;gap:1.5rem}
.qol-panel h3{color:var(--dark);     font-size: 1rem;  margin: 1rem 0;    font-weight: 500;}
.qol-panel p{color:var(--muted);font-size:.8rem;line-height:1.5;margin:0}
.qol-panel p strong{color:var(--dark);font-weight:700}
@media(max-width:768px){.qol-inner{grid-template-columns:1fr;gap:1.25rem}.qol-section{padding:3.5rem 1.25rem}}

/* Assurance / provenance - the trust band */
.assure-section{background:linear-gradient(155deg,#061816 0%,#0c322c 55%,#0a3b30 100%);color:hsl(var(--on-band-dark));padding:6.5rem 2rem}
.assure-inner{max-width:1080px;margin:0 auto}
.assure-lede-row{display:flex;align-items:flex-start;justify-content:space-between;gap:2.5rem;margin-bottom:3.5rem}
.assure-lede{max-width:46rem}
/* The magpie fills the gutter right of the lede. The section is literally about Content
   Credentials, so a signed genAI animal here is the argument in the flesh - curiosity by
   design. Contained (in flow, not absolute), stacks under the copy on narrow screens. */
.assure-mascot{width:clamp(120px,25vw,300px);flex-shrink:0;filter:drop-shadow(0 14px 34px rgba(0,0,0,.45))}
@media(max-width:820px){.assure-lede-row{flex-direction:column}.assure-mascot{width:min(42vw,180px);align-self:flex-start}}
.assure-eyebrow{display:inline-block;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.12em;color:var(--light);margin-bottom:1rem}
.assure-section h2{font-size:2.5rem;line-height:1.08;color:hsl(var(--on-band-dark));margin:0 0 1.25rem}
.assure-lead{font-size:1.12rem;line-height:1.75;color:hsl(var(--on-band-dark) / .72);margin:0}
.assure-lead strong{color:hsl(var(--on-band-dark));font-weight:700}
.assure-lead a{color:var(--light);text-decoration:underline;text-underline-offset:2px}
.assure-main{max-width:46rem;margin-bottom:3.5rem}
.assure-checks{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1.5rem}
.assure-checks li{display:flex;gap:1rem;align-items:flex-start}
.assure-check-ic{width:1.7rem;height:1.7rem;flex-shrink:0;color:var(--green);margin-top:.05rem}
.assure-check-ic svg{width:100%;height:100%}
.assure-checks strong{display:block;color:hsl(var(--on-band-dark));font-size:1.05rem;font-weight:700;margin-bottom:.25rem}
.assure-checks li>div>span{color:hsl(var(--on-band-dark) / .6);font-size:.92rem;line-height:1.55;display:block}
/* auto-fit rather than a fixed 3: the "Made on your device" card retired into the
   sovereignty statement (plan 117 block 3), so this grid now carries two cards in
   English and three in the locales that still ship the old JSON. */
.assure-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:1px;background:rgba(0,0,0,.35);border:1px solid rgba(255,255,255,.08);border-radius:14px;overflow:hidden;margin-bottom:2.25rem}
.assure-card{background:rgba(255,255,255,.03);padding:1.9rem 1.6rem;transition:background .15s}
.assure-card:hover{background:rgba(255,255,255,.06)}
.assure-card-ic{display:block;width:1.7rem;height:1.7rem;color:var(--light);margin-bottom:.85rem}
.assure-card-ic svg{width:100%;height:100%}
.assure-card strong{display:block;color:hsl(var(--on-band-dark));font-size:1rem;margin-bottom:.45rem}
.assure-card p{color:hsl(var(--on-band-dark) / .55);font-size:.88rem;line-height:1.6;margin:0}
.assure-cta a{color:var(--green);font-weight:700;text-decoration:none;font-size:1.02rem}
.assure-cta a:hover{text-decoration:underline}
/* Hand-off to the docs. The section above makes claims; these are where the
   reasoning and the caveats actually live, so they read as a quiet index rather
   than five more marketing cards - small caps label, hairline separators, no fill
   until you hover. */
.assure-docs{margin-top:2.75rem;padding-top:2rem;border-top:1px solid rgba(255,255,255,.1)}
.assure-docs-label{display:block;font-size:.6875rem;text-transform:uppercase;letter-spacing:.12em;
  font-weight:700;color:hsl(var(--on-band-dark) / .45);margin-bottom:1.1rem}
.assure-docs-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:.5rem}
.assure-doc{display:block;padding:.9rem 1rem;border-radius:12px;border:1px solid transparent;
  text-decoration:none;transition:background .15s,border-color .15s}
.assure-doc:hover{background:rgba(255,255,255,.045);border-color:hsl(var(--on-band-dark) / .12);text-decoration:none}
.assure-doc-ic{display:block;width:1.15rem;height:1.15rem;color:var(--green);margin-bottom:.55rem}
.assure-doc-ic svg{width:100%;height:100%}
.assure-doc strong{display:block;color:hsl(var(--on-band-dark));font-size:.9375rem;margin-bottom:.3rem}
.assure-doc-desc{display:block;color:hsl(var(--on-band-dark) / .55);font-size:.8125rem;line-height:1.5}
@media(max-width:768px){.assure-section{padding:4.5rem 1.25rem}.assure-section h2{font-size:1.95rem}.assure-grid{grid-template-columns:1fr}}
[data-theme="dark"] .qol-section{background:hsl(var(--background))}
[data-theme="dark"] .qol-panel{background:rgba(255,255,255,.035);border-color:hsl(var(--on-band-dark) / .1);box-shadow:none}
[data-theme="dark"] .qol-panel h3,[data-theme="dark"] .qol-panel p strong{color:hsl(var(--on-band-dark))}
[data-theme="dark"] .qol-panel p{color:hsl(var(--on-band-dark) / .6)}

/* Everywhere section */
.everywhere-section{padding:5rem 2rem;background:hsl(var(--band-dark));color:hsl(var(--on-band-dark))}
.everywhere-inner{display:flex;flex-direction:column;gap:1.5rem;max-width:1400px;margin:0 auto;text-align:start}
/* Mascot beside the TITLE only (per the brief), bigger than before; copy + chips run full
   width on their own lines below. */
.everywhere-head{display:flex;align-items:center;justify-content:space-between;gap:2.5rem}
.everywhere-head h2{margin:0;flex:1 1 auto}
.everywhere-mascot{width:clamp(300px,34vw,600px);flex-shrink:0}
.everywhere-section h2{color:hsl(var(--on-band-dark))}
.everywhere-copy{font-size:1.125rem;line-height:1.75;color:hsl(var(--on-band-dark) / .65);margin:0 0 1rem}
.everywhere-chips{display:flex;flex-wrap:wrap;justify-content:flex-start;gap:1rem}
@media(max-width:768px){.everywhere-head{flex-direction:column;align-items:flex-start;gap:1.25rem}.everywhere-mascot{width:min(82vw,440px)}}
.everywhere-chip{display:inline-flex;flex-direction:column;align-items:center;gap:.625rem;padding:1.25rem 1.75rem;background:rgba(255,255,255,.05);border-radius:14px;color:hsl(var(--on-band-dark));font-size:.95rem;font-weight:700;min-width:7rem;transition:background .2s}
.everywhere-chip:hover{background:rgba(255,255,255,.09)}
.everywhere-chip svg{width:2rem;height:2rem;color:var(--green);flex-shrink:0}
.everywhere-chip span{letter-spacing:.02em}
.everywhere-models{max-width:1400px;margin:4rem auto 0}
.everywhere-models-intro{text-align:center;color:hsl(var(--on-band-dark));font-size:1rem;margin:0 0 2rem}
.everywhere-models-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem}
.everywhere-model{position:relative;display:flex;align-items:stretch;gap:1.5rem;padding:3.5rem 1.75rem 2rem;background:rgba(255,255,255,.05);border-radius:18px;transition:background .2s,border-color .2s}
.everywhere-model:hover{background:rgba(255,255,255,.08);border-color:hsl(var(--on-band-dark) / .16)}
.everywhere-model-main{flex:0 0 2em;min-width:0}
.everywhere-model-num{position:absolute;top:-1rem;left:50%;transform:translateX(-50%);ox-shadow: inset 0 0 0 .25px #0002, inset 0 1px 1.5px #fff9, 0 .2rem .4rem #0002;
    text-shadow: 0 1px .5px #fff2;width:fit-content;font-size:.75rem;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:var(--dark);background:rgba(48,186,120,1.14);padding:.32rem .7rem;border-radius:999px;margin:0}
.everywhere-model-icon{width:2.25rem;height:2.25rem;color:var(--green);display:block;margin-bottom:.9rem}
.everywhere-model h3{color:var(--green);font-size:1.2rem;margin:0;}
.everywhere-model p{flex:1;min-width:0;font-size:.95rem;line-height:1.65;color:hsl(var(--on-band-dark) / .6);margin:0;padding-left:1.5rem}
@media(max-width:768px){.everywhere-models-grid{grid-template-columns:1fr;gap:2rem}.everywhere-models{margin-top:2.5rem}}

/* What's a tool */
.whats-a-tool{padding:4.5rem 3.5rem;background:var(--border)}
.whats-inner{max-width:var(--col-cap);margin-right:auto;margin-left:0}
.whats-a-tool .whats-inner>h2{color:var(--dark);font-size:2rem;margin-bottom:.625rem;text-align:center}
.tool-lead{max-width:100%;margin:0 0 2rem;font-size:1.0625rem;line-height:1.8;color:var(--muted);text-align:center}
.tool-anatomy{display:flex;flex-wrap:wrap;gap:.75rem;max-width:100%;margin:0 0 2rem;justify-content:center;align-items:center}
.tool-part{background:hsl(var(--card));border:1px solid var(--border);border-radius:12px;padding:1rem 1.25rem;text-align:center;flex:1;min-width:110px;box-shadow:0 2px 8px rgba(12,50,44,.07);transition:box-shadow .15s}
.tool-part:hover{box-shadow:0 4px 16px rgba(12,50,44,.12)}
.tool-part-file{font-family:'SUSE Mono','SF Mono',monospace;font-size:.75rem;background:hsl(var(--muted));color:var(--dark);padding:.2em .55em;border-radius:4px;display:inline-block;margin-bottom:.5rem;font-weight:600}
.tool-part-name{font-weight:700;color:var(--dark);font-size:.8125rem;margin-bottom:.2rem}
.tool-part-desc{font-size:.73rem;color:var(--muted);line-height:1.45}
.tool-plus{font-size:1.5rem;color:var(--border);font-weight:300;flex-shrink:0;align-self:center}
.tool-features{display:grid;grid-template-columns:repeat(2,1fr);gap:.75rem;margin-bottom:1.75rem}
.tool-feature{background-color:hsl(var(--on-band-dark) / .14);border:1px solid var(--border);border-radius:12px;padding:1.25rem 1.375rem;display:flex;flex-direction:column;gap:.35rem;transition:box-shadow .15s}
.tool-feature:hover{box-shadow:0 4px 16px rgba(12,50,44,.1)}
.tool-feature-icon{width:1.375rem;height:1.375rem;color:var(--green);margin-bottom:.25rem;flex-shrink:0}
.tool-feature-icon svg{width:100%;height:100%}
.tool-feature strong{font-size:.9rem;color:var(--dark);font-weight:700;line-height:1.25}
.tool-feature p{font-size:.8rem;color:var(--muted);line-height:1.55;margin:0}
/* Floats at the bottom seam where the two columns meet (relative to .platform-whats-wrap). */
.try-now-callout{position:absolute;left:50%;bottom:0;transform:translate(-50%,50%);z-index:10;width:min(92%,640px);background:#01564a;border-radius:14px;padding:1.5rem 1.75rem;display:flex;align-items:center;gap:1.5rem;flex-wrap:wrap;box-shadow: 0 10px 30px rgba(0,0,0,.2), inset 0 .06rem .1rem #fff2}
.try-now-text{flex:1;min-width:0}
.try-now-text strong{        color: hsl(var(--on-band-dark));font-size:.9375rem;display:block;margin-bottom:.35rem;font-weight:700}
.try-now-text p{color:hsl(var(--on-band-dark));font-size:.85rem;line-height:1.6;margin:0}

/* Design import segment ("bring your existing files") */
.import-section{background:linear-gradient(180deg,#fff 0%,var(--pale) 100%);padding:7rem 2rem 5rem}
.import-inner{max-width:1080px;margin:0 auto}
.import-lede{display:flex;align-items:center;justify-content:center;gap:2.5rem;max-width:64rem;margin:0 auto 3rem;text-align:start}
.import-lede-text{max-width:46rem}
.import-mascot{width:clamp(180px,22vw,340px);flex-shrink:0}
@media(max-width:820px){.import-lede{flex-direction:column;text-align:center}}
.import-eyebrow{display:inline-block;font-size:.6875rem;text-transform:uppercase;letter-spacing:.14em;font-weight:700;color:var(--green);background:rgba(48,186,120,.1);padding:.4em .9em;border-radius:2em;margin-bottom:1.25rem}
.import-section h2{color:var(--dark);margin-bottom:1.25rem}
.import-lead{font-size:1.0625rem;line-height:1.8;color:var(--muted);margin:0}
.import-lead strong{color:var(--dark);font-weight:700}
.import-sources{display:grid;grid-template-columns:repeat(5,1fr);gap:1rem;margin-bottom:1.75rem}
.import-source{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;background:hsl(var(--card));border:0;    box-shadow: 0 .3rem 1rem #00000016;border-radius:14px;padding:1.5rem 1rem;transition:box-shadow .15s,transform .15s}
.import-source:hover{box-shadow:0 8px 24px rgba(12,50,44,.1);transform:translateY(-2px)}
.import-badge{display:inline-flex;align-items:center;box-shadow:inset 0 0 0 1px #0002, inset 0 1.25px 2px #fff9,  0 .2rem .4rem #0002;justify-content:center;width:2.75rem;height:2.75rem;border-radius:12px;background:var(--b,#30ba78);color:hsl(var(--on-band-dark));font-weight:800;font-size:.9rem;letter-spacing:-.01em}
.import-source strong{color:var(--dark);font-size:.95rem;font-weight:700}
.import-fmt{font-family:'SUSE Mono','SF Mono',monospace;font-size:.72rem;color:var(--muted);letter-spacing:.02em}
.import-flow{display:flex;align-items:stretch;gap:.5rem;margin-bottom:2.75rem}
.import-step{flex:1;min-width:0;background:var(--border);border:1px solid var(--border);border-radius:14px;padding:1.5rem 1.25rem;text-align:center}
.import-step-icon{width:1.75rem;height:1.75rem;color:var(--muted); margin:0 auto .75rem}
.import-step-icon svg{width:100%;height:100%; stroke-width:1.5px}
.import-step strong{display:block;color:var(--dark);font-size:.9rem;margin-bottom:.35rem}
.import-step p{font-size:.8rem;color:var(--muted);line-height:1.55;margin:0}
.import-arrow{align-self:center;color:var(--green);flex-shrink:0;font-size:1.4rem;font-weight:300;line-height:1}
.import-points{display:grid;grid-template-columns:repeat(3,1fr);gap:1.25rem;margin-bottom:2.5rem}
.import-point{background:hsl(var(--card));border:1px solid var(--border);border-radius:14px;padding:1.75rem 1.5rem}
.import-point-icon{width:2rem;height:2rem;color:var(--green);margin-bottom:.9rem}
.import-point-icon svg{width:100%;height:100%}
.import-point strong{display:block;color:var(--dark);font-size:1rem;margin-bottom:.5rem}
.import-point p{font-size:.875rem;color:var(--muted);line-height:1.65;margin:0}
.import-cta-row{text-align:center}
.import-more{display:inline-flex;align-items:center;gap:.4rem;font-weight:700;color:var(--green);font-size:.95rem}
.import-more:hover{text-decoration:none;color:var(--dark)}
@media(max-width:820px){
  .import-sources{grid-template-columns:repeat(2,1fr)}
  .import-points{grid-template-columns:1fr}
  .import-flow{flex-direction:column}
  .import-arrow{transform:rotate(90deg)}
}
@media(max-width:480px){
  .import-section{padding:4.5rem 1.25rem 3.5rem}
}
/* A landing mascot wrapped with its Content Credential. The mascot's sizing class
   (.about-mascot / .audience-mascot / .everywhere-mascot: width, flex-shrink, drop-shadow)
   rides on THIS span, so it stays the flex child it was; the img just fills it, and the
   corner credential positions against it. NOT .asset-cred (that is width:100%, for the
   full-column docs hero). */
.mascot-cred{position:relative;display:block;flex-shrink:0}
.mascot-cred>img{display:block;width:100%;height:auto;margin:0}
/* Keep a landing mascot's credit INSIDE its box (the brief), unlike a screenshot's
   caption which deliberately overhangs the artwork edge. Clamp the line to the mascot's
   own width and let the pills WRAP into a compact stack rather than run off the side. The
   glyph stays bottom-anchored; the expanded line grows upward within the box. */
.mascot-cred .shot-cred{max-width:calc(100% - 1rem)}
.mascot-cred .shot-cred-line{max-width:100%}
.mascot-cred .shot-cred-row{flex-wrap:wrap}
.audience-header{display:flex;align-items:center;justify-content:center;gap:2rem;padding:4rem 3rem 1.75rem}
.audience-header-text{text-align:start}
.audience-mascot{width:clamp(200px,26vw,430px);flex-shrink:0;filter:drop-shadow(0 6px 20px rgba(12,50,44,.18))}
@media(max-width:900px){.audience-mascot{width:clamp(160px,22vw,280px)}}
@media(max-width:600px){.audience-header{flex-direction:column;gap:1rem;padding:2.5rem 1.25rem 1.25rem}.audience-header-text{text-align:center}.audience-mascot{width:clamp(140px,44vw,220px)}}
.hero-founded{margin-top:2rem; max-width:15em;}
/* About section */
.about-section{padding:5rem 1.5rem;background:hsl(var(--band-dark));color:hsl(var(--on-band-dark))}
.about-inner{max-width:960px;margin:0 auto}
.about-header{display:flex;align-items:center;gap:3rem;margin-bottom:3.5rem}
.about-header-text{flex:1;min-width:0}
.about-mascot{width:clamp(200px,26vw,360px);flex-shrink:0;filter:drop-shadow(0 16px 40px rgba(0,0,0,.5))}
/* A second, smaller animal opposite the koala - the About section IS the "adorable
   Australian animals" section, so a companion here is on-theme, not clutter. */
.about-mascot-2{width:clamp(120px,15vw,190px);flex-shrink:0;filter:drop-shadow(0 12px 30px rgba(0,0,0,.45))}
.about-section h2{color:hsl(var(--on-band-dark));margin-bottom:1rem}
.about-section h3{font-size:.75rem;font-weight:800;color:hsl(var(--on-band-dark) / .5);text-transform:uppercase;letter-spacing:.16em;margin:3rem 0 1.25rem;text-align:center}
.about-lead{font-size:1.0625rem;color:hsl(var(--on-band-dark) / .7);line-height:1.85;margin:0}
.about-items{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem}
.about-item{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);border-radius:16px;padding:2rem 1.75rem;display:flex;flex-direction:row;align-items:flex-start;gap:1.125rem}
.about-item-icon{width:3.25rem;height:3.25rem;flex-shrink:0;color:var(--green)}
.about-item-icon svg{width:100%;height:100%}
.about-item p{color:hsl(var(--on-band-dark) / .6);line-height:1.8;font-size:.9375rem;margin:0}
.about-item strong{color:hsl(var(--on-band-dark));font-weight:700}
/* FAQ */
.faq-section{padding:5rem 2rem;background:hsl(var(--background))}
.faq-inner{margin:0 auto; max-width: calc(var(--col-cap) * 1.4);}
.faq-section h2{text-align:center;margin-bottom:.5rem}
.faq-lead{text-align:center;color:var(--muted);font-size:1.0625rem;margin-bottom:2.5rem}
.faq-list{display:flex;flex-direction:column;gap:.75rem}
.faq-item{border:1px solid var(--border);border-radius:12px;background:var(--pale);overflow:hidden;transition:box-shadow .15s,border-color .15s}
.faq-item[open]{box-shadow:0 6px 20px rgba(12,50,44,.12)}
.faq-q{display:flex;align-items:center;justify-content:space-between;gap:1.25rem;padding:1.25rem 1.5rem;font-weight:700;color:var(--dark);font-size:1.0625rem;line-height:1.4;cursor:pointer;list-style:none}
.faq-q::-webkit-details-marker{display:none}
.faq-q:hover{color:var(--green)}
.faq-chevron{flex-shrink:0;width:1.25rem;height:1.25rem;color:var(--green);transition:transform .2s}
.faq-chevron svg{width:100%;height:100%}
.faq-item[open] .faq-chevron{transform:rotate(180deg)}
.faq-a{padding:0 1.5rem 1.4rem;color:var(--muted);line-height:1.75}
.faq-a p{margin-bottom:.75rem}
.faq-a p:last-child{margin-bottom:0}
/* Screenshots inside an FAQ answer. faq.md is the one .md that renders into the
   LANDING accordion rather than an /info/*.html docs page, so it never picks up
   the .docs-content img rules above - and a shot baseline carries an intrinsic
   width="1440", which without this would render at full size and push the whole
   landing page sideways. Same framing as the docs-page treatment, capped to the
   answer column. */
.faq-a img{max-width:100%;height:auto;display:block;margin:.9rem 0 0;border-radius:10px}
.faq-a img[src*="/info/shots/"]{border:1px solid hsl(var(--border));box-shadow:0 6px 24px #0002}
@media(max-width:800px){
  .about-header{flex-direction:column;text-align:center;gap:1.75rem}
  .about-mascot{width:clamp(160px,44vw,260px)}
  .about-items{grid-template-columns:1fr}
}
/* Hero entrance */
@keyframes heroUp{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.hero-heading{animation:heroUp .7s ease both .22s}
.hero .subtitle{animation:heroUp .65s ease both .38s}
.hero-cta{animation:heroUp .65s ease both .52s}
.hero-trust{animation:heroUp .65s ease both .65s}
.hero-inner{display:flex;align-items:center;gap:4rem;max-width:1400px;margin:0 auto;width:100%}
.hero-heading{margin-bottom:1.5rem;position:relative}
.hero h1{margin-bottom:0;text-align:start;letter-spacing:0;font-weight:100}
.hero-details{flex:1;text-align:start}
.hero .subtitle{margin-left:.5rem;max-width:none}
.hero-cta{justify-content:flex-start}
.hero-trust{justify-content:flex-start}
@media(max-width:600px){.hero-inner{flex-direction:column;text-align:center}.hero-heading{flex-direction:column;gap:1rem;align-items:center}.hero h1{text-align:center;font-size:clamp(2rem,10vw,4rem)}.hero-details{text-align:center}.hero-cta{justify-content:center}.hero-trust{justify-content:center}}
/* Scroll reveal */
.reveal{opacity:0;transform:translateY(22px);transition:opacity .55s ease,transform .55s ease}
.reveal.visible{opacity:1;transform:none}
.reveal-1{transition-delay:.05s}
.reveal-2{transition-delay:.15s}
.reveal-3{transition-delay:.25s}
.reveal-4{transition-delay:.35s}
.reveal-5{transition-delay:.45s}
.reveal-6{transition-delay:.55s}
/* Mobile: snappier reveals - drop the stagger and shorten the fade so content
   doesn't lag behind the scroll (the observer also triggers earlier on mobile). */
@media(max-width:768px){
  .reveal{transition-duration:.3s}
  .reveal-1,.reveal-2,.reveal-3,.reveal-4,.reveal-5,.reveal-6{transition-delay:0s}
}
@media(prefers-reduced-motion:reduce){
  .hero h1,.hero .subtitle,.hero-cta,.hero-trust{animation:none}
  .reveal,.reveal.visible{opacity:1;transform:none;transition:none}
}
[data-theme="dark"] .audience-section{border-bottom-color:var(--border)}
[data-theme="dark"] .audience-header{background:linear-gradient(180deg,#0a1f16 0%,#061816 100%)}
[data-theme="dark"] .audience-title{color:var(--text)}
[data-theme="dark"] .audience-tabs{background:hsl(var(--background));border-bottom-color:var(--border)}
[data-theme="dark"] .audience-tab{background:hsl(var(--card))}
[data-theme="dark"] .audience-tab:hover{color:var(--green);background:hsl(var(--card))}
[data-theme="dark"] .card-tagline{color:var(--text)}
[data-theme="dark"] .card-intro{color:var(--muted)}
[data-theme="dark"] .faq-section{background:hsl(var(--background))}
[data-theme="dark"] .faq-section h2{color:var(--text)}
[data-theme="dark"] .faq-item{background:hsl(var(--muted))}
[data-theme="dark"] .faq-q{color:var(--text)}
[data-theme="dark"] .card-benefits strong{color:var(--text)}
[data-theme="dark"] .tool-part{background:hsl(var(--card))}
[data-theme="dark"] .tool-part-file{background:hsl(var(--muted))}
[data-theme="dark"] .tool-part-name{color:var(--text)}
[data-theme="dark"] .whats-a-tool .whats-inner>h2{color:var(--text)}
[data-theme="dark"] .tool-feature{background:hsl(var(--card))}
[data-theme="dark"] .tool-feature strong{color:var(--text)}
[data-theme="dark"] .import-section{background:linear-gradient(180deg,#061816 0%,var(--pale) 100%)}
[data-theme="dark"] .import-section h2{color:var(--text)}
[data-theme="dark"] .import-source,[data-theme="dark"] .import-step{background:hsl(var(--card))}
[data-theme="dark"] .import-point{background:hsl(var(--card))}
[data-theme="dark"] .import-source strong,[data-theme="dark"] .import-step strong,[data-theme="dark"] .import-point strong{color:var(--text)}
/* ── Why we built Lolly + old-way vs Lolly-way matrix ─────────────────────── */
.why-section{padding:5rem 1.5rem;background:var(--lolly-coin-glow)}
.why-inner{max-width:1080px;margin:0 auto}
.why-lede{display:flex;align-items:center;justify-content:center;gap:2.5rem;max-width:62rem;margin:0 auto 2.5rem;text-align:start}
.why-lede-text{max-width:44rem}
.why-mascot{width:clamp(180px,22vw,340px);flex-shrink:0}
@media(max-width:820px){.why-lede{flex-direction:column;text-align:center}}
.why-eyebrow{display:inline-block;font-size:.75rem;font-weight:800;text-transform:uppercase;letter-spacing:.14em;color:var(--green);margin-bottom:.75rem}
.why-section h2{font-size:clamp(1.8rem,4vw,2.5rem);color:var(--dark);line-height:1.12;margin-bottom:1rem}
.why-lead{color:var(--muted);font-size:1.0625rem;line-height:1.7}
.why-frustrations{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-bottom:2.5rem}
.why-frustration{background:hsl(var(--card));border:0; box-shadow: inset 0 1px #fff1, 0 .2em .5em #0002;border-radius:14px;padding:1.5rem 1.375rem;text-align:center}
.why-frustration-ic{display:inline-flex;width:2.75rem;height:2.75rem;align-items:center;justify-content:center;border-radius:50%;background:rgba(254,124,63,.12);color:var(--orange);margin-bottom:.75rem}
.why-frustration-ic svg{width:1.4rem;height:1.4rem}
.why-frustration strong{display:block;color:var(--dark);margin-bottom:.35rem;font-size:1.0625rem}
.why-frustration p{color:var(--muted);font-size:.9rem;line-height:1.55}
.matrix{display:grid;grid-template-columns:1fr 1fr;gap:.75rem;align-items:stretch}
.matrix-head{font-weight:800;text-transform:uppercase;letter-spacing:.08em;font-size:.8rem;padding:.85rem 1.1rem;border-radius:10px;text-align:center}
.matrix-head--old{background:rgba(90,112,103,.14);color:var(--muted)}
.matrix-head--new{background:var(--green);color:#fff}
.matrix-cell{display:flex;gap:.7rem;align-items:flex-start;padding:1rem 1.15rem;border-radius:12px;font-size:.95rem;line-height:1.5}
.matrix-cell--old{background:hsl(var(--card) / .7);border:0;color:var(--muted)}
.matrix-cell--new{background:rgba(48,186,120,.08);color:var(--text);box-shadow:0 2px 12px rgba(48,186,120,.12)}
.matrix-mark{flex-shrink:0;width:1.35rem;height:1.35rem;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;font-size:.78rem;font-weight:800;margin-top:.05rem}
.matrix-cell--old .matrix-mark{background:hsl(var(--card) / 1 );color:var(--muted)}
.matrix-cell--new .matrix-mark{        background: hsl(var(--accent-foreground) / .1);    color: var(--accent-foreground);}
@media(max-width:720px){.why-frustrations{grid-template-columns:1fr}.matrix{grid-template-columns:1fr;gap:.5rem}.matrix-head{display:none}.matrix-cell--old{margin-top:.5rem}}
/* Dark-theme surfaces for the pale Why section. */
[data-theme="dark"] .why-section{background:hsl(var(--background))}
[data-theme="dark"] .why-section h2{color:var(--text)}
[data-theme="dark"] .why-frustration{background:hsl(var(--card))}
[data-theme="dark"] .why-frustration strong{color:var(--text)}
[data-theme="dark"] .matrix-cell--old{background:hsl(var(--card))}
[data-theme="dark"] .matrix-cell--new{background:hsl(var(--card))}


/* Docs layout */
.docs-wrap{display:grid;grid-template-columns:220px 1fr;max-width:1180px;margin:0 auto;min-height:calc(100vh - 3.5rem - 60px)}
.docs-sidebar{padding:2rem 1.25rem;border-right:1px solid var(--border);position:sticky;top:3.75rem;height:calc(100vh - 3.75rem);overflow-y:auto}
/* Format / convert side-door pages (plan 116 workstream A). */
.sidedoor-eyebrow{display:flex;align-items:center;gap:.5rem;font-size:.75rem;text-transform:uppercase;letter-spacing:.1em;font-weight:700;color:var(--green);margin-bottom:.75rem}
.sidedoor-eyebrow svg{width:1.25rem;height:1.25rem}
.sidedoor .sidedoor-full{color:var(--muted);font-size:1.0625rem;margin:-1rem 0 1.25rem}
.sidedoor-dir{font-weight:600;margin:0 0 1rem}
.sidedoor-lead{font-size:1.0625rem;line-height:1.7;margin-bottom:1.5rem}
.sidedoor-contrast{color:var(--muted);font-size:.9375rem;line-height:1.65;border-inline-start:3px solid var(--green);padding-inline-start:.85rem;margin:0 0 1.5rem}
.sidedoor-promise{list-style:none;padding:0;display:flex;flex-wrap:wrap;gap:.5rem .75rem;margin:0 0 1.5rem}
.sidedoor-promise li{display:inline-flex;align-items:center;gap:.4em;background:hsl(var(--card));border:1px solid var(--border);border-radius:999px;padding:.3rem .85rem;font-size:.875rem;font-weight:600}
.sidedoor-promise li::before{content:"✓";color:var(--green);font-weight:700}
.sidedoor-cta{display:inline-flex;align-items:center;gap:.4em;background:var(--green);color:#fff;text-decoration:none;font-weight:700;padding:.7rem 1.4rem;border-radius:.6rem;margin-bottom:.5rem}
.sidedoor-cta:hover{filter:brightness(1.05)}
.sidedoor-convert-cols{display:flex;flex-wrap:wrap;align-items:stretch;gap:1rem;margin:0 0 1.5rem}
.sidedoor-col{flex:1 1 15rem;background:hsl(var(--card));border:1px solid var(--border);border-radius:.75rem;padding:1rem 1.15rem}
.sidedoor-col-label{display:block;font-size:.6875rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);font-weight:700;margin-bottom:.35rem}
.sidedoor-col strong{display:block;font-size:1.35rem;margin-bottom:.5rem}
.sidedoor-col p{margin:0;font-size:.9375rem;color:var(--muted);line-height:1.6}
.sidedoor-convert-arrow{align-self:center;color:var(--green);font-size:1.6rem;font-weight:700}
.sidedoor-detail{margin-top:2rem;padding-top:1.5rem;border-top:1px solid var(--border)}
.sidedoor-feats{list-style:none;padding:0;display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 1rem}
.sidedoor-feats li{background:hsl(var(--card));border:1px solid var(--border);border-radius:.5rem;padding:.3rem .75rem;font-size:.8125rem}
.sidedoor-carry{color:var(--muted);margin:.5rem 0;line-height:1.6}
.sidedoor-prov{font-weight:600;margin:.5rem 0}
.sidedoor-offline{color:var(--muted);margin:.25rem 0 0}
.sidedoor-foot{margin-top:2.5rem;padding-top:1.5rem;border-top:1px solid var(--border)}
.sidedoor-foot-why{margin:0 0 .5rem}
.sidedoor-foot-links{display:flex;flex-wrap:wrap;gap:.5rem 1.5rem}
.sidedoor-foot-link{font-weight:700;text-decoration:none;color:var(--green)}
.sidedoor-foot-link:hover{text-decoration:underline}
.sidebar-label{font-size:.6875rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted);font-weight:700;margin:1.5rem 0 .5rem}
.sidebar-label:first-child{margin-top:0}
.sidebar-home{display:block;font-size:.8125rem;color:var(--muted)!important;margin-bottom:1rem;padding:0!important}
.sidebar-home:hover{color:var(--green)!important;background:none!important}
/* Docs search - in the TOPBAR, not the rail. It sits with the other whole-site
   controls (language, theme, launch) because it acts on the whole site: the rail
   answers "what is there", the box answers "where is the thing I already know I
   want", and that second question does not belong inside the first question's list.
   It is also where readers look for it.

   Logical properties throughout so the Arabic build mirrors without a second rule
   set. The field lives inside a fixed-height (3.75rem) nav on purpose - .docs-sidebar
   pins its sticky top and height to that number, so this must not change it. */
.docs-search{position:relative;flex:none;margin-inline-start:.25rem}
.docs-search-input{inline-size:11rem;box-sizing:border-box;padding:.4rem .7rem;font:inherit;font-size:.8125rem;
  color:hsl(var(--on-band-dark));background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.16);border-radius:2em;
  transition:inline-size .18s ease,background .15s ease,border-color .15s ease}
.docs-search-input::placeholder{color:hsl(var(--on-band-dark) / .5)}
.docs-search-input:hover{background:rgba(255,255,255,.14)}
.docs-search-input:focus{outline:none;inline-size:15rem;background:rgba(255,255,255,.18);border-color:var(--green)}
/* Only on genuinely small screens does the field collapse to a puck that opens on
   focus. The breakpoint is 560px, not the ~900px that looks natural in isolation,
   because the nav sheds its whole link row at 1100px (see the hamburger block) -
   from there down to 560px the bar is just brand, search and three controls, so a
   readable field fits easily and shrinking it early would cost function for nothing.
   Below 560px the remaining controls do start to crowd, so it becomes a glyph. */
@media(max-width:560px){
  .docs-search-input{inline-size:2.1rem;padding-inline:0;text-align:center}
  .docs-search-input:focus{inline-size:min(60vw,14rem);padding-inline:.7rem;text-align:start}
  .docs-search-input::placeholder{color:transparent}
}
/* FIXED, not absolute: the nav is a horizontally scrolling flex bar, so an absolute
   panel would be clipped to a 3.75rem-tall strip and scroll away with the field.
   Fixed escapes it (nothing on the ancestor chain establishes a containing block -
   no transform, no filter, no backdrop-filter on nav, which is what would trap it),
   and the script positions it from the input's rect on scroll and resize.

   Width: wide enough for a result to read as three lines of prose rather than a
   column of single words. It is a floating overlay anchored to the field, so it is
   free to be wider than whatever it hangs from. */
.docs-search-results{position:fixed;z-index:110;inline-size:min(30rem,calc(100vw - 2rem));max-height:min(60vh,28rem);overflow-y:auto;background:hsl(var(--popover));border:1px solid var(--border);border-radius:10px;box-shadow:0 10px 34px #00000026;padding:.25rem}
/* A hit is explicitly a flex COLUMN rather than a block. It used to be a block that
   had to out-specify the rail's .docs-sidebar a{display:flex} - and when that
   fight was lost the three spans became flex items in a ROW, so every result was
   three narrow columns of one-word-per-line text. The panel no longer lives in the
   rail, but declaring the axis means the layout cannot be decided by whichever
   ancestor rule happens to win a specificity contest later. */
.docs-search-hit{display:flex;flex-direction:column;align-items:stretch;padding:.5rem .6rem;border-radius:7px;color:var(--text)}
.docs-search-hit .hit-h{font-size:.875rem;font-weight:600;color:var(--dark);line-height:1.35}
.docs-search-hit .hit-c{font-size:.6875rem;color:var(--green);margin-top:.1rem}
.docs-search-hit .hit-x{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:.8125rem;color:var(--muted);margin-top:.25rem;line-height:1.45}
.docs-search-hit:hover,.docs-search-hit.is-active{background:var(--pale);text-decoration:none}
.docs-search-empty{padding:.6rem .55rem;font-size:.8125rem;color:var(--muted)}
[data-theme="dark"] .docs-search-results{background:hsl(var(--popover));box-shadow:0 10px 34px #0000008c}
/* --dark is NOT remapped by the [data-theme="dark"] theme (it overrides --text/--muted/--border
   /--pale only), so every var(--dark) foreground is near-black on the dark panel.
   The docs headings solve it the same way one block up: repoint to --text. */
[data-theme="dark"] .docs-search-hit .hit-h{color:var(--text)}
.sidebar-pathway{font-size:.9375rem;font-weight:700;color:var(--dark);margin-bottom:.75rem;padding-bottom:.75rem;border-bottom:1px solid var(--border)}
.docs-sidebar a{display:flex;align-items:flex-start;gap:.5rem;padding:.3rem .5rem;font-size:.875rem;color:var(--text);border-radius:5px}
.docs-sidebar a:hover{color:var(--green);background:var(--pale);text-decoration:none}
.docs-sidebar a.active{color:var(--green);font-weight:600;background:var(--pale)}
/* Sidebar glyphs. Quiet by default so the LABEL still leads and the icon is the
   second cue rather than a competing one; they take the link's colour on hover and
   when active, so the row reads as one object. Fixed 1.05em box + flex-start keeps
   a two-line label aligned to the glyph's first line, not centred against it. */
.docs-sidebar a .sidebar-ic{flex:none;width:1.05em;height:1.05em;margin-top:.12em;color:var(--muted);opacity:.75}
.docs-sidebar a .sidebar-ic svg{width:100%;height:100%;display:block}
.docs-sidebar a:hover .sidebar-ic,.docs-sidebar a.active .sidebar-ic{color:inherit;opacity:1}
/* Two pages keep a hue of their own (see buildSidebar): AI and Inclusive Design.
   It is carried by a SOFT TINTED ROW, not a bright glyph - a saturated purple or
   pink sitting next to SUSE green read as two brands arguing rather than one
   system with an accent. The tint does the signalling, the glyph just picks it up,
   and both hues are desaturated toward the palette's own muted register so the
   column still reads green-first. Same landmark, no fight. */
.docs-sidebar a:has(.sidebar-ic.is-ai){background:#f5f2fd}
.docs-sidebar a:has(.sidebar-ic.is-inclusive){background:#fdf1f7}
.docs-sidebar a .sidebar-ic.is-ai{color:#6f5cc6;opacity:1}
.docs-sidebar a .sidebar-ic.is-inclusive{color:#c14b83;opacity:1}
/* Hover and active keep the row in its own hue instead of snapping to green -
   a landmark that changes colour when you touch it stops being a landmark. */
.docs-sidebar a:hover:has(.sidebar-ic.is-ai),.docs-sidebar a.active:has(.sidebar-ic.is-ai){background:#ece6fb;color:#5b4aab}
.docs-sidebar a:hover:has(.sidebar-ic.is-inclusive),.docs-sidebar a.active:has(.sidebar-ic.is-inclusive){background:#fbe3ef;color:#a83c6f}
.docs-sidebar a:hover .sidebar-ic.is-ai,.docs-sidebar a.active .sidebar-ic.is-ai{color:#5b4aab}
.docs-sidebar a:hover .sidebar-ic.is-inclusive,.docs-sidebar a.active .sidebar-ic.is-inclusive{color:#a83c6f}
/* Dark mode: a tint, not a fill - low-alpha over the near-black page so the row
   glows rather than becoming a slab, and the glyph lifts to stay legible. */
/* AI/inclusive sidebar chips: the base rules paint a light lilac/pink chip with
   dark ink, which on a dark ground (dark AND brand) would be light-link-text on
   a light chip. Brand has no overrides of its own, so it takes the dark chip
   treatment too. */
[data-theme="dark"] .docs-sidebar a:has(.sidebar-ic.is-ai),[data-theme="brand"] .docs-sidebar a:has(.sidebar-ic.is-ai){background:rgba(139,124,246,.13)}
[data-theme="dark"] .docs-sidebar a:has(.sidebar-ic.is-inclusive),[data-theme="brand"] .docs-sidebar a:has(.sidebar-ic.is-inclusive){background:rgba(244,114,182,.12)}
[data-theme="dark"] .docs-sidebar a .sidebar-ic.is-ai,[data-theme="brand"] .docs-sidebar a .sidebar-ic.is-ai{color:#b9a8f7}
[data-theme="dark"] .docs-sidebar a .sidebar-ic.is-inclusive,[data-theme="brand"] .docs-sidebar a .sidebar-ic.is-inclusive{color:#f2a9c9}
[data-theme="dark"] .docs-sidebar a:hover:has(.sidebar-ic.is-ai),[data-theme="dark"] .docs-sidebar a.active:has(.sidebar-ic.is-ai),[data-theme="brand"] .docs-sidebar a:hover:has(.sidebar-ic.is-ai),[data-theme="brand"] .docs-sidebar a.active:has(.sidebar-ic.is-ai){background:rgba(139,124,246,.2);color:#cbbdff}
[data-theme="dark"] .docs-sidebar a:hover:has(.sidebar-ic.is-inclusive),[data-theme="dark"] .docs-sidebar a.active:has(.sidebar-ic.is-inclusive),[data-theme="brand"] .docs-sidebar a:hover:has(.sidebar-ic.is-inclusive),[data-theme="brand"] .docs-sidebar a.active:has(.sidebar-ic.is-inclusive){background:rgba(244,114,182,.19);color:#ffc2dd}
[data-theme="dark"] .docs-sidebar a:hover .sidebar-ic.is-ai,[data-theme="dark"] .docs-sidebar a.active .sidebar-ic.is-ai,[data-theme="brand"] .docs-sidebar a:hover .sidebar-ic.is-ai,[data-theme="brand"] .docs-sidebar a.active .sidebar-ic.is-ai{color:#cbbdff}
[data-theme="dark"] .docs-sidebar a:hover .sidebar-ic.is-inclusive,[data-theme="dark"] .docs-sidebar a.active .sidebar-ic.is-inclusive,[data-theme="brand"] .docs-sidebar a:hover .sidebar-ic.is-inclusive,[data-theme="brand"] .docs-sidebar a.active .sidebar-ic.is-inclusive{color:#ffc2dd}
/* Icon bullet lists (the <!--i:key--> md marker - policy pages). Logical
   properties so the Arabic build mirrors correctly. */
.docs-content ul.icon-list{list-style:none;padding-inline-start:0;display:flex;flex-direction:column;gap:.9rem}
.docs-content ul.icon-list>li.ic{display:flex;align-items:flex-start;gap:.75rem}
/* Technology marks (the <!--l:key--> md marker - docs/logos.ts). Sized in em so a
   mark tracks whatever text it sits in, capped so it cannot become an illustration,
   and nudged onto the baseline the way an inline image needs to be. Muted by default
   at the same weight the sidebar glyphs use: these are landmarks for the eye, not a
   second reading of the sentence. Slightly OVER 1em (1.1) on purpose - these marks
   are dense little pictures, and at exactly the type size they read as smudges.

   HEADINGS CARRY NO MARKS. A heading is the page's own name for a section and the
   thing a reader scans to navigate by; a glyph in front of it competes for that job.
   Where a section really is about a technology, the marks go ABOVE it as a block
   (.doc-logo-block) instead, and the heading keeps its line to itself.

   Colour is deliberately just currentColor at reduced opacity - no per-brand fills.
   The site colours exactly two glyph families on purpose (the AI and inclusive-design
   sidebar rows); twenty brand palettes down a build page would be a carnival, and
   every mark here is someone else's trademark, which is not ours to restyle. If one
   ever earns its colour, it is one rule against [data-logo="key"]. */
.doc-logo{display:inline-block;width:1.1em;height:1.1em;max-width:1.35em;max-height:1.35em;vertical-align:-.18em;margin-inline-end:.3em;opacity:.75}
.doc-logo svg{width:100%;height:100%;display:block}
/* A mark inside a table cell carries the row, so it keeps full presence. */
.docs-content td .doc-logo{opacity:.85}
/* The block form (<!--lb:a b--> on its own line, before a major heading): the same
   marks given air and scale, so scrolling past one reads as arriving somewhere.
   Centred, generous margin above and below, and still monochrome - the size is what
   makes it an event, not colour. Sized in px rather than em: this row belongs to the
   PAGE's rhythm, not to the type around it, and every block should be the same size
   on every page. */
.doc-logo-block{display:flex;justify-content:center;align-items:center;gap:1.5rem;margin:4.5rem 0 2rem;color:var(--muted);opacity:.55}
.doc-logo-mark{display:block;width:44px;height:44px}
.doc-logo-mark svg{width:100%;height:100%;display:block}
@media(max-width:600px){.doc-logo-block{gap:1.1rem;margin:3rem 0 1.5rem}.doc-logo-mark{width:36px;height:36px}}
/* Two columns from a ::: cols fence. The pairing IS the argument on
   /info/status-quo - what happened on the left, what it cost on the right - so the
   two read together rather than one after the other. Below 900px they stack, which
   keeps the reading order intact because the source order is already correct. */
.md-cols{display:grid;grid-template-columns:1fr 1fr;gap:1.75rem 3rem;margin:2rem 0 2.5rem}
.md-cols .md-col>h2:first-child{margin-top:0;font-size:1.25rem}
.md-cols .md-col>ul{margin-bottom:0}
.md-cols .md-col li{font-size:.9375rem}
@media(max-width:900px){.md-cols{grid-template-columns:1fr;gap:2.25rem}}
/* A ::: timeline fence draws its icon list as a sequence: a rail joining each step,
   the way the change history in Verify draws a file's steps. Same visual grammar for
   the same idea - things that happened, in order. Used for the frictions we all
   accumulated, and for the rogue-agent scenario walked step by step. Sequences only:
   a set of causes or commitments stays a plain icon list, because a rail between
   unordered things says something untrue about them. */
.md-timeline .icon-list{position:relative;gap:1.35rem}
.md-timeline .icon-list>li.ic{position:relative;padding-bottom:.1rem}
.md-timeline .icon-list>li.ic .li-icon{position:relative;z-index:1;
  width:2rem;height:2rem;flex:none;display:grid;place-items:center;border-radius:999px;
  background:var(--pale);border:1.5px solid var(--border);color:var(--muted)}
.md-timeline .icon-list>li.ic .li-icon svg{width:1rem;height:1rem}
/* The rail: drawn from each item down to the next, so it stops cleanly at the last
   one instead of trailing into whitespace. */
.md-timeline .icon-list>li.ic:not(:last-child)::before{content:'';position:absolute;
  left:1rem;top:2rem;bottom:-1.35rem;width:1.5px;background:var(--border)}
@media(max-width:640px){.md-timeline .icon-list>li.ic .li-icon{width:1.75rem;height:1.75rem}
  .md-timeline .icon-list>li.ic:not(:last-child)::before{left:.875rem;top:1.75rem}}
.li-icon{flex-shrink:0;width:1.35rem;height:1.35rem;margin-top:.2rem;color:var(--green)}
.li-icon svg{width:100%;height:100%;display:block}
.docs-content{padding:2.75rem 3.5rem 6rem;min-width:0}
/* No band (a page with no h1 at all): the column is back to clearing the fixed nav
   by itself, which is what the 6rem was always for. */
.docs-content.no-mast{padding-top:6rem}
/* ── Article masthead (docsMasthead + DOCS_MASTHEAD_SCRIPT) ───────────────────
   The page's own h1 over the chip field, FULL VIEWPORT WIDTH: the band is a sibling
   of .docs-wrap, so the sidebar rail and the article both begin underneath it. That
   is the landing page's own grammar (its hero spans the window and the content
   starts below), and a band inset to one column would have read as an illustration
   inside the article rather than as the top of the page.

   The heading is left-aligned ON THE CONTENT GRID rather than centred: the landing
   hero sets its h1 to text-align:start inside a centred max-width box, and lining
   this one up with the column the article is about to start in makes the band feel
   structural instead of pasted on. Logical padding, so an RTL locale mirrors it.

   isolation:isolate keeps the canvas's blend mode inside the band - without it the
   dark theme's color-dodge would reach the page behind. */
.docs-masthead{position:relative;isolation:isolate;overflow:hidden;padding:calc(3.75rem + 3.25rem) 0 3rem;min-height:clamp(14rem,30vh,20rem);display:flex;flex-direction:column;justify-content:flex-end;background:linear-gradient(180deg,var(--pale) 0%,var(--page) 100%)}
/* The dark plate stays a PLATE - a green a couple of steps up from the page - because
   color-dodge divides by the backdrop: over near-black (#061816) the chips resolve to
   near-black too and the field disappears. The gradient's last stop still reaches the
   page colour, so the band ends where the article begins. */
[data-theme="dark"] .docs-masthead{background:linear-gradient(180deg,#16482f 0%,#0b2b21 58%,var(--page) 100%)}
/* Same box as .docs-wrap, then indented past the rail: the h1 starts exactly where
   the article's text will. Below 768px the rail is gone and so is the indent. */
.docs-mast-inner{position:relative;z-index:2;max-width:1180px;width:100%;margin:0 auto;padding-inline:calc(220px + 3.5rem) 3.5rem}
.docs-mast-canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0;opacity:.55}
/* Dark reuses the landing's own recipe (color-dodge over a dark plate); light gets
   a normal blend, because dodging on a near-white band blows the chips out to
   invisible white. Blend and opacity live here rather than in the JS: they are how
   the field MEETS the page, and the page's own theme rules already know that. */
[data-theme="dark"] .docs-mast-canvas{mix-blend-mode:color-dodge;opacity:.6}
/* Two scrims, both above the canvas and below the h1 (::before/::after are z-index 1,
   the heading is 2). The first is legibility insurance - the heading is currentColor,
   so decoration must never be allowed to eat its contrast; the second melts the band
   into the page it sits on, which at full bleed is the whole difference between a
   masthead and a banner. */
.docs-masthead::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;background:radial-gradient(ellipse 70% 60% at 30% 88%,var(--mast-scrim) 0%,transparent 72%)}
.docs-masthead::after{content:'';position:absolute;left:0;right:0;bottom:0;height:50%;z-index:1;pointer-events:none;background:linear-gradient(180deg,transparent 0%,var(--page) 94%)}
:root{--mast-scrim:rgba(255,255,255,.82)}
[data-theme="dark"]{--mast-scrim:rgba(6,24,22,.72)}
/* Brand theme is a dark-teal ground: without an override it fell back to the white
   :root scrim, washing the glow white. Ride the brand primary so the halo is the
   active brand's own colour (pine green for SUSE, the mounted brand's primary else). */
[data-theme="brand"]{--mast-scrim:hsl(var(--primary) / .4)}
/* Qualified with .docs-content (0,2,1) on purpose: the article rule .docs-content h1
   is (0,1,1) and gives every page heading a bottom rule and 2rem of padding. Inside a
   band that rule is a second horizontal line under a heading that already sits on
   one, so it has to be out-specified rather than tied with. */
.docs-masthead h1{margin:0;padding:0;border-bottom:0;color:var(--dark)}
[data-theme="dark"] .docs-masthead h1{color:var(--text)}
@media(max-width:768px){.docs-masthead{padding:calc(3.75rem + 1.75rem) 0 1.75rem;min-height:9rem}.docs-mast-inner{padding-inline:1rem}}
/* ── Banked masthead art (MASTHEADS + docs-art.ts) ────────────────────────────
   A signed artifact inlined in place of the chip canvas. SAME BAND: same padding,
   min-height, scrims and hoisted h1 - the only thing that changes is what is painted
   behind the heading, so a page that gains banked art does not also silently gain a
   different top. The art takes the canvas's z-index (0), under both scrims, so the
   heading's contrast is protected by the same two layers whatever the artwork does.

   width/height 100% on an SVG artifact's root rather than its own attributes: the
   band's height is the band's decision (it is furniture on a page, not a picture), and
   an SVG that keeps its own preserveAspectRatio then fills it the way it was drawn to.
   A fragment (markup + script) sizes ITSELF inside this box - it brought its own CSS,
   and a blanket rule here would fight it. */
.docs-mast-art{position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none}
.docs-mast-art>svg{display:block;width:100%;height:100%}
/* The credential is a mark on the ARTWORK, so it hangs off the band's own corner like a
   screenshot's does - but the band is full-bleed, so it is inset to the same gutter the
   footer and nav use rather than sitting against the window edge. Above both scrims
   (z-index 3) or the melt gradient would fade the one line on the band that must stay
   legible; pointer-events are restored by .shot-cred-btn/.shot-cred-line themselves. */
.docs-masthead--art .shot-cred--mast{inset-block-end:.8rem;inset-inline-end:1.2rem;z-index:3}
/* A banked masthead carries a full claim - signer, file, kind, date, an AI pill and its
   model, plus all three actions - which is far more than the one short row .shot-cred-row's
   nowrap was written for, so on the mast the line overflows its padded card and the facts
   row lands adrift. Same fix the asset/mascot/figure marks use: give the card room and let
   the row WRAP into a compact stack inside it, right-aligned to the anchored corner. */
.docs-masthead--art .shot-cred--mast .shot-cred-line{max-width:min(30rem,calc(100vw - 3rem))}
.docs-masthead--art .shot-cred--mast .shot-cred-row{flex-wrap:wrap}
/* ── Figures (::: figure - a banked artifact in the text flow) ────────────────
   Content, not decoration: it sits in the column with the prose that argues with it,
   and its caption is a real caption (the showcase's, which this deliberately matches -
   two inlined-vector blocks that read differently would be two grammars for one idea).
   The credential rides INSIDE the figcaption rather than on the artwork's corner: a
   figure's provenance is part of what the caption says. */
.docs-figure{position:relative;margin:2.5rem auto;max-width:100%;min-width:0}
.docs-figure-art{position:relative;border-radius:1.2em;overflow:hidden}
.docs-figure-art>svg{display:block;width:100%;height:auto}
.docs-figure figcaption{margin-top:.9rem;font-size:.8125rem;color:var(--muted);text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:.5rem}
.docs-figure figcaption p{margin:0}
/* In the flow, not anchored: .shot-cred is absolutely positioned for the corner-mark
   case, and inside a caption that would drop it onto the artwork above. Static, centred,
   and the glyph BEFORE the line (row, not row-reverse) so it reads left-to-right as a
   caption does. */
.docs-figure figcaption .shot-cred{position:static;flex-direction:row;align-items:center;
  justify-content:center;width:auto;max-width:100%}
/* Open at rest, like the AI-stance hero's and for the same reason: in a caption a mark
   that only appears on hover is a caption hiding half of itself, and a figure's own
   origin is frequently the point the surrounding page is making. */
.shot-cred--figure .shot-cred-line{opacity:1;pointer-events:auto;transform:none}
.docs-figure figcaption .shot-cred-line{align-items:center;max-width:100%}
.docs-figure figcaption .shot-cred-row{flex-wrap:wrap;justify-content:center}
/* "Copy signed source" is a BUTTON among two links (it does something to the reader's
   machine rather than going somewhere), so it is stripped back to look like them -
   the alternative, a link with a click handler, would lie to the keyboard and to the
   status bar about where it goes. */
button.shot-cred-copy{border:0;background:none;padding:.1em .35em;font:inherit;font-size:.6875rem;
  font-weight:600;color:inherit;cursor:pointer}
.shot-cred-copy-label{pointer-events:none}
/* The model pill's entity chip sits tight against its label, like the signer's. */
.prov-model .prov-entity{margin-inline:.18em 0}
.docs-content img{height:auto;    max-width: min(100%, 40em);    height: auto;   margin: 0 auto; display: block;}
/* App screenshots (docs/shots.json captures) read at full column width, framed like a window. */
.docs-content img[src*="/info/shots/"]{max-width:100%;min-width:50%;border-radius:1.2em;
  /* The <img> carries hardcoded width/height attrs to reserve layout space (no
     settle shift). Let CSS win over them so a tall PORTRAIT shot (the mobile
     /verify captures) is bounded by HEIGHT and shrinks its width to match, rather
     than filling the column and running metres down the page. object-fit keeps the
     aspect ratio while width/height are auto. */
  object-fit:contain;width:auto;height:auto;max-height:50em;
  box-shadow: inset 0 0 0 1px hsl(var(--border)), 0 3px 6px #0002, 0 6px 2em #00000014}
/* The frame ring is INK, so it has to invert: a black hairline is invisible on a
   near-black page, which is why the shots read as unframed in dark mode. Light
   ring, slightly stronger (a 1px white line at 6% disappears against a screenshot
   whose own edges are light), plus a deeper drop so the card still sits ON the
   page rather than in it. */
[data-theme="dark"] .docs-content img[src*="/info/shots/"]{
  box-shadow: inset 0 0 0 1px hsl(var(--border)), 0 3px 8px #00000073, 0 6px 2em #0000004d}

/* ── Screenshot settle ──────────────────────────────────────────────────────
   Every shot enters lifted, with a wide diffuse shadow, then lands: the shadow
   tightens under it as it rises the last 30px into place. Read as a sheet being
   set down on the page.

   fit-content, not 100%: the wrapper must hug the IMAGE, because the credential
   line is positioned against this box. A portrait shot in a wide column would
   otherwise strand its credential in the empty margin.

   NO scale, on purpose: an <img> of an SVG is rasterised by Blink at the
   composited scale, so a transform-SCALED shot goes soft DURING the motion and
   snaps crisp only at rest. Since the whole point of these shots is that they are
   vector - razor-sharp at any size - the settle only translates and fades; it
   never scales, so the artwork stays crisp through the entire motion. The
   showcase block below makes the vector argument outright (it animates real
   geometry). */
.shot{display:block;position:relative;width:fit-content;max-width:100%;margin:0 auto}
.shot>img{margin:0}
/* The hidden start state is gated on .shots-motion, which the pre-paint script in
   <head> adds. A shot must NEVER be able to strand itself at opacity 0: with no
   JS (or a script that failed to parse) the class is absent, no rule below
   matches, and every screenshot is simply visible. The gate is set before first
   paint rather than by the observer at end-of-body, or a long page would paint
   the shots once and then blink them out to animate them back in. */
@media(prefers-reduced-motion:no-preference){
  .shots-motion .shot{opacity:0;transform:translateY(30px);
    transition:opacity .5s ease,transform .75s cubic-bezier(.16,.84,.3,1)}
  /* Every rule that undoes the start state carries the SAME .shots-motion
     qualifier, so it matches the (0,2,0) above. A bare .shot--in here is
     (0,1,0) and loses to the hidden state - which would leave every screenshot
     on the site invisible forever. */
  .shots-motion .shot--in{opacity:1;transform:none}
  .shots-motion .shot>img{transition:box-shadow .75s cubic-bezier(.16,.84,.3,1)}
  .shots-motion .shot:not(.shot--in)>img{box-shadow:inset 0 0 0 1px hsl(var(--border)), 0 28px 60px #00000030}
  [data-theme="dark"] .shots-motion .shot:not(.shot--in)>img{box-shadow:inset 0 0 0 1px hsl(var(--border)), 0 28px 60px #00000073}
}

/* ── Screenshot credential line ─────────────────────────────────────────────
   A photo-credit that can be checked. At rest: one imprint glyph in the corner at
   low opacity. On hover, keyboard focus or tap it becomes a line of provenance
   pills plus two actions.

   NO JavaScript is required for the reveal, and that is a deliberate a11y choice.
   The line is never display:none - it is opacity 0 with pointer-events off - so it
   stays in the accessibility tree and in tab order, and :focus-within brings it
   into view the instant a keyboard reaches one of its links. A hidden-until-JS
   popover would have had to lie about aria-expanded in the no-JS case; this cannot.
   The script only adds tap-to-open and Escape-to-close, which hover cannot do. */
/* width:max-content is doing real work. An absolutely positioned box shrink-to-fits
   against its containing block, so on a 247px-wide shot the line was squeezed until
   even "signed by Lolly" broke across three lines. Given intrinsic width and an
   inline-end anchor with no inline-start, it lays out at its natural size and grows
   LEFTWARDS across (and past) the artwork, like a caption.

   pointer-events are handed to the children, not the container: the closed line
   still occupies its full box, and a transparent 350px strip that opens on hover
   would fire whenever the pointer crossed the bottom of the shot. */
/* align-items:flex-END, not center: the line is a flex SIBLING of the glyph and is
   opacity-0 (never display:none), so it keeps its box in the layout at rest. Under
   center a taller line - which is exactly what the second, anatomy row makes it -
   would re-centre the glyph upward off its anchored corner, on every shot, expanded or
   not. Bottom-aligning pins the glyph to inset-block-end regardless of how tall the
   invisible line beside it is, so the resting mark is identical whether or not a shot
   has a readable second row. */
.shot-cred{position:absolute;inset-block-end:.55rem;inset-inline-end:.7rem;z-index:2;
  display:flex;align-items:flex-end;justify-content:flex-end;gap:.4rem;flex-direction:row-reverse;
  width:max-content;max-width:min(28rem,calc(100vw - 3rem));pointer-events:none}
/* Quiet by COLOUR and size, never by transparency. This mark used to rest at
   opacity:.34, which faded the glyph's strokes along with its puck - so the ripple
   path dissolved into whatever the screenshot's own corner happened to be and, at
   1.4rem, read as a smudge rather than a mark. A credential nobody can make out is
   not discreet, it is decoration.

   So: the puck stays opaque enough to GUARANTEE the glyph's contrast whatever sits
   behind it (screenshot corners are unpredictable - a white card, a dark timeline, a
   photo), and the glyph is muted against that puck instead of against the shot. Rest
   is legible; hover only sharpens it. */
.shot-cred-btn{display:grid;place-items:center;width:1.4rem;height:1.4rem;flex:none;padding:0;
  border:0;border-radius:50%;cursor:pointer;color:var(--muted);background:hsl(var(--popover) / 0.9);
  box-shadow:0 1px 3px #00000024;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);pointer-events:auto;
  transition:color .2s ease,background .2s ease,box-shadow .2s ease}
.shot-cred-btn svg{width:.9rem;height:.9rem;display:block}
/* Approaching the shot at all sharpens it; it never shouts. */
.shot:hover .shot-cred-btn,.showcase:hover .shot-cred-btn{color:var(--dark)}
.shot-cred-btn:hover,.shot-cred-btn:focus-visible{color:var(--dark);background:hsl(var(--popover));box-shadow:0 2px 6px #0003}
/* Sized against the VIEWPORT, never the shot. Some shots are a 236px-wide crop of
   one control, and a line clamped to that width wraps into a stack taller than the
   artwork. Because .shot-cred is anchored to the inline-end and nothing on the way
   up clips, a wider line simply extends back across the shot (and past its edge on
   a small one), which is how a caption behaves rather than how a box does. */
.shot-cred-line{display:flex;flex-direction:column;align-items:flex-end;gap:.16rem;
  max-width:min(26rem,calc(100vw - 3rem));padding:.28rem .45rem;border-radius:.9rem;
  background:hsl(var(--popover) / 0.87);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  box-shadow:0 2px 10px #0000001f, inset 0 0 0 1px hsl(var(--border));
  opacity:0;pointer-events:none;transform:translateX(.4rem);
  transition:opacity .22s ease,transform .22s ease}
/* Hover is keyed off the GLYPH (and then the line itself, so the pointer can travel
   onto it without it closing) rather than off the container, which is
   pointer-events:none for the reason given above. */
.shot-cred-btn:hover + .shot-cred-line,.shot-cred-btn:focus-visible + .shot-cred-line,
.shot-cred-line:hover,.shot-cred:focus-within .shot-cred-line,
.shot-cred[data-open] .shot-cred-line{opacity:1;pointer-events:auto;transform:none}
/* The "try it" offer under a shot. In the FLOW and OUTSIDE the .shot wrapper, not in
   the overlay: the credential is a mark on the artwork, this is a line of the page, and
   they must not compete. Outside matters structurally too - .shot-cred is anchored to
   the wrapper's bottom edge, so a link inside it pushes that edge down and the mark
   lifts off the artwork's corner onto the caption. Centred under the picture (the shot
   itself is a centred fit-content box), quiet until approached. */
.shot-try{display:block;margin-block-start:.5rem;text-align:center;
  font-size:.8125rem;font-weight:600;color:var(--muted)}
.shot-try::after{content:' →'}
.shot-try:hover,.shot-try:focus-visible{color:var(--green);text-decoration:underline}
/* A PAGE ASSET's credential (the AI stance hero): open at rest, because the file's
   history is what the surrounding page is arguing about rather than a footnote to a
   screenshot. Same mark, same line, same two links - only the resting state differs,
   so a reader who never hovers still sees who signed the picture they are looking at. */
.shot-cred--asset .shot-cred-line{opacity:1;pointer-events:auto;transform:none}
/* Full column width, and nothing else: page artwork sizes itself (the hero is
   width:100% a few rules down), so the wrapper only has to be a positioned box the
   mark can hang off. An image that wants 100% of a fit-content parent resolves to
   zero, which is the other reason this is not a .shot. */
.asset-cred{display:block;position:relative;width:100%}
.asset-cred>img{display:block;width:100%;height:auto;margin:1em auto}
/* A page-asset credential rests OPEN on a full-width hero, so - unlike a screenshot's
   caption, which deliberately overhangs a narrow crop (see the .shot-cred notes above) -
   it must stay INSIDE the frame: there is a whole column of room, so a spill past the
   edge like the one on /input-not-impersonation is just a bug. Same fix the mascot credit
   uses a few rules down: clamp the line to the artwork, and let the rows WRAP into a
   compact stack rather than run off the side. The glyph stays anchored; the line grows
   within the box. */
.asset-cred .shot-cred{max-width:calc(100% - 1.4rem)}
.asset-cred .shot-cred-line{max-width:18em}
.asset-cred .shot-cred-row{flex-wrap:wrap}
/* not-a-pipe keeps the DEFAULT centred, 40em-capped image (see .docs-content img above),
   so its .asset-cred wrapper is the full column - wider than the picture - and a mark
   anchored to the wrapper's edge hangs off into the margin. Hug the wrapper to the same cap
   so the credential aligns to the artwork's real edge. (the-flood escapes this only because
   it overrides its image to width:100% further down, filling the wrapper.) */
.asset-cred[data-shot="/info/not-a-pipe.webp"]{max-width:min(100%,40em);margin-inline:auto}
/* Its caption "Ceci n'est pas une pipe" runs along the bottom edge, and that writing is the
   whole point of the picture - so this hero's mark sits mid-height rather than in the bottom
   corner where it would cover the words it is arguing about. */
.asset-cred[data-shot="/info/not-a-pipe.webp"] .shot-cred{inset-block-end:50%}
/* The line is a stack of ROWS, and a shot with no readable file has exactly one of
   them - so the column above is byte-identical to the single row it replaced. The
   second row (what the file is made of) only ever appears inside the expanded line,
   which is the only state the line has: at rest the whole thing is opacity 0. The
   glyph itself does not move when the second row is present, because .shot-cred
   bottom-anchors it (align-items:flex-end) rather than centring it against the line.

   nowrap on the ROW, not on the line: the row still refuses to break "signed by
   Lolly" across lines, and a stack of two short rows is shorter than the four-row
   wrap the one-row rule was written to prevent. */
.shot-cred-row{display:flex;align-items:center;gap:.3rem;flex-wrap:nowrap;justify-content:flex-end}
/* The line's pills are chips on a chip, so they sit a step quieter than the ones
   the prose uses - and they must not inherit the docs paragraph line-height, which
   would make the row twice as tall as the glyph beside it. */
.shot-cred-row>*{flex:none}
.shot-cred-line .prov-pill{font-size:.6875rem;line-height:1.3;padding:.1em .5em;margin:0;white-space:nowrap}
.shot-cred-line .prov-seal{width:.8em;height:.8em}
.shot-cred-do{font-size:.6875rem;font-weight:600;white-space:nowrap;padding:.1em .35em;border-radius:.6em}
.shot-cred-do:hover{background:var(--pale);text-decoration:underline}
/* An AI declaration is not a detail to be discovered - if a shot ever carries one,
   its mark arrives already at full contrast and wearing the brand ring, so it reads
   as a statement rather than as the same quiet glyph every other shot has. */
.shot-cred--ai .shot-cred-btn{color:hsl(var(--on-band-dark));background:hsl(var(--band-dark));box-shadow:0 0 0 2px var(--green)}
/* Dark mode: same contract, inverted. The puck is near-opaque for the same reason -
   a dark screenshot's corner is not reliably darker than the puck - and the glyph is
   a muted PALE against it, not a full-white one, so it stays quiet without becoming
   the invisible stroke this used to be. */
[data-theme="dark"] .shot-cred-btn{color:#93a8a0;background:hsl(var(--popover) / 0.9);box-shadow:0 1px 3px #0006}
[data-theme="dark"] .shot:hover .shot-cred-btn,[data-theme="dark"] .showcase:hover .shot-cred-btn{color:var(--pale)}
[data-theme="dark"] .shot-cred-btn:hover,[data-theme="dark"] .shot-cred-btn:focus-visible{color:var(--pale);background:hsl(var(--popover));box-shadow:0 2px 6px #0008}
[data-theme="dark"] .shot-cred--ai .shot-cred-btn{color:var(--dark);background:var(--light)}
[data-theme="dark"] .shot-cred-line{background:hsl(var(--popover) / 0.93);box-shadow:0 2px 10px #0007, inset 0 0 0 1px hsl(var(--border))}
[data-theme="dark"] .shot-cred-do:hover{background:hsl(var(--foreground) / 0.08)}
@media(prefers-reduced-motion:reduce){.shot-cred-line{transition:none;transform:none}}
/* Narrow columns: the line would be wider than the shot, so it stacks above the
   glyph instead of beside it and takes the shot's full width. */
@media(max-width:640px){
  .shot-cred{flex-direction:column;align-items:flex-end;inset-inline-start:.7rem}
  .shot-cred-line{max-width:100%;transform:translateY(.4rem)}
}

/* ── Geometry showcase (::: showcase - one inlined vector shot) ─────────────
   Scroll drives --p from 0 to 1. Everything that moves is geometry:

     camera  the svg viewBox is lerped from a centre crop out to full extent (JS -
             viewBox is an attribute, not a CSS property). The captured strokes are
             non-scaling-stroke, so they stay hairline all the way in. No re-raster,
             no blur, at any zoom - the whole point of the block.
     ink     grayscale(1 - p): the drawing arrives as ink and takes on its colour.
             A filter function list CAN transition, unlike the url() case above.
     order   each leaf shape appears when p passes its share of the paint order, so
             the map assembles itself layer by layer (water, then road classes by
             weight) instead of fading in as one flat picture.

   --p is set by JS, so with no JS the fallbacks below (p:1) render the finished
   artwork at full extent, in colour, every layer visible. */
.showcase{--p:1;margin:2.5rem auto;max-width:100%;width:fit-content}
/* The radius lives on the artwork, NOT as overflow:hidden on the stage - the stage
   also holds the credential line, which is allowed to extend past the artwork's
   edge, and a clipping stage would cut it off. */
.showcase-stage{position:relative;border-radius:1.2em;
  box-shadow:inset 0 0 0 1px hsl(var(--border)), 0 3px 6px #0002, 0 6px 2em #00000014}
[data-theme="dark"] .showcase-stage{
  box-shadow:inset 0 0 0 1px hsl(var(--border)), 0 3px 8px #00000073, 0 6px 2em #0000004d}
/* The <img> the build emits, and the live SVG that replaces it, must occupy the
   same box - the swap happens under the reader's eyes and any size change would
   read as a jump rather than an upgrade. */
.showcase-fallback,.showcase-art{display:block;width:min(100%,40em);height:auto;margin:0;border-radius:1.2em}
.showcase-art{filter:grayscale(calc(1 - var(--p)))}
/* The stagger. Each leaf gets --i (its paint-order index) and the root gets --n
   (the total) from the showcase script; ×2.2 fades each shape over a fraction of
   the scroll rather than all of it, so the layers overlap into one motion.

   The +1 is what makes this read as drawing rather than loading: it puts the FIRST
   leaf (the sheet the artwork sits on) on screen at p=0, so the block opens as
   blank paper and the ink arrives onto it. Without it every layer including the
   background starts at zero, and the opening frame is an empty box that looks like
   a screenshot that failed to load. */
.showcase-art [data-sc-i]{opacity:clamp(0,calc((var(--p) * var(--n) - var(--i) + 1) * 2.2),1)}
.showcase figcaption{margin-top:.9rem;font-size:.8125rem;color:var(--muted);text-align:center;
  max-width:34em;margin-inline:auto}
.showcase figcaption p{margin:0}
@media(prefers-reduced-motion:reduce){
  /* No camera, no ink phase, no stagger - the finished artwork, still. */
  .showcase{--p:1 !important}
  .showcase-art{filter:none}
  .showcase-art [data-sc-i]{opacity:1}
}

/* ── Theme twin: two committed files, one shown ────────────────────────────
   A "dark=1" recipe ships a second baseline captured with the app pinned dark, and
   the reader's own toggle decides which one is on screen. NOT a <picture> with a
   prefers-color-scheme source: the site's dark mode is a CLASS the reader flips,
   so a media-query source would follow the OS and contradict the toggle.

   Ungated (no .shots-motion, no media query) so it holds with JS off, and scoped
   to .shot--dual so a shot with no twin is byte-identical to before. Each twin
   carries its OWN credential line - two separately signed files. */
/* Every img rule here is qualified with the ELEMENT as well as the class: the base
   .docs-content img rule sets display:block at (0,1,1), so a bare .shot-alt (0,1,0)
   loses and BOTH twins render, one under the other. */
.shot--dual>img.shot-alt,.shot--dual .shot-cred--alt{display:none}
[data-theme="dark"] .shot--dual>img:not(.shot-alt),[data-theme="dark"] .shot--dual .shot-cred:not(.shot-cred--alt){display:none}
[data-theme="dark"] .shot--dual>img.shot-alt{display:block}
[data-theme="dark"] .shot--dual .shot-cred--alt{display:flex}

/* Provenance pills (the typed markers authors write in the markdown - see inline()).
   A provenance line reads as
   data tags in sentence order, so the hierarchy is carried by weight and fill, not
   by size: ACTORS solid and darkest, SIGNATURES outlined with a seal, then the
   mechanical detail (actions, filenames, sizes) quiet enough to skim past.
   The paragraph stays ordinary inline text - a flex row would make every word
   between the pills its own flex item and strand the connecting commas. */
.prov-pill{display:inline-block;border-radius:999px;padding:.16em .62em;font-size:.8125rem;
  line-height:1.4;margin:0 .08em;vertical-align:baseline}
/* Every surface below is a THEME TOKEN, never a literal - the tokens flip with
   [data-theme="dark"], a hex does not. A hardcoded light fill under light-on-dark text is how
   these pills went unreadable in dark mode the first time. */
.prov-entity{background:hsl(var(--band-dark));color:hsl(var(--on-band-dark));font-weight:700;letter-spacing:.01em}
[data-theme="dark"] .prov-entity{background:#12463a}  /* lifted off the near-black page so the chip still reads as a chip */
.prov-sig{color:var(--text);font-weight:600;background:rgba(48,186,120,.14)}
/* An actor inside a signature is WHITE ON GREEN in both themes - a signature is the
   one claim that must look identical wherever it is read. The fill is a deepened
   brand green rather than --green itself: white on #30ba78 is about 2.2:1, which
   fails for 13px text, and a signature nobody can read is worse than an off-swatch
   one. This keeps the hue and clears 4.5:1. */
.prov-sig .prov-entity{background:#14784d;color:hsl(var(--on-band-dark));margin-inline:.18em 0}
/* Inline, not a flex child: the pill's baseline must be its TEXT baseline so it
   sits on the same line as the prose around it. The glyph is nudged optically. */
/* The seal is the one glyph in the pill that must read at a glance, and --green
   on --pale is the weakest pairing in the set (a mid-green on a tinted background
   in BOTH themes). It takes the theme's ink instead: near-black on the light pill,
   white on the dark one. The literal #fff is safe here because it lives inside
   [data-theme="dark"], so it flips with the theme rather than surviving it. */
.prov-seal{width:.95em;height:.95em;margin-inline-end:.34em;vertical-align:-.14em;color:var(--dark)}
[data-theme="dark"] .prov-seal{color:hsl(var(--on-band-dark))}
.prov-act{background:var(--pale);color:var(--text);font-weight:550;border:1px solid transparent}
[data-theme="dark"] .prov-act{border-color:var(--border)}
/* A filename wraps rather than truncating - it is evidence the caption is naming,
   so hiding its tail hides the point. NOTE: never give this overflow:hidden -
   on an inline-block that moves the baseline to the bottom margin edge (CSS 2.1
   10.8.1) and the pill visibly drops below the line it sits in. */
.prov-file{background:var(--pale);color:var(--muted);border:1px solid var(--border);
  font-family:'SUSE Mono','SF Mono',monospace;font-size:.75rem;
  white-space:normal;overflow-wrap:anywhere;max-width:100%}
.prov-detail{color:var(--muted);font-variant-numeric:tabular-nums;font-size:.8125rem}
/* The caption sits under the hero as a caption, not as body copy. The extra
   leading is what keeps a wrapped chain of padded pills off the rows above and
   below - with normal leading the pill boxes collide even though the text does not. */
.docs-content p:has(.prov-pill){margin-top:.9rem;font-size:.9375rem;line-height:2.15;color:var(--muted)}

/* The AI-stance hero photo carries a three-manifest C2PA chain (Google's two as
   ingredients, Lolly's own on top) that readers are invited to verify, so its
   bytes are exactly what Lolly exported - never re-encode it in a build step.
   Full column width: it is the page's one image and the argument's evidence. */
.docs-content img[src*="the-flood"]{width:100%;max-width:100%;border-radius:1.2em;box-shadow:0 3px 6px #0002, 0 6px 2em #0001}
.docs-content h2{font-size:1.5rem;font-weight:700;letter-spacing:normal;text-transform:none;border-top:1px solid var(--border);padding-top:2rem;margin-top:2.5rem;margin-bottom:.75rem;color:var(--dark)}
.docs-content h2:first-of-type{border-top:none;padding-top:0;margin-top:0}
.docs-content h3{font-size:1.15rem;margin-top:1.75rem;margin-bottom:.5rem;color:var(--dark)}
.docs-content h4{font-size:1rem;margin-top:1.25rem;margin-bottom:.35rem;color:var(--muted)}
/* The top nav is fixed at 3.75rem, so a heading landed on by an #anchor (the jump
   nav below, a search result, a shared deep link) would otherwise sit UNDER it. Same
   idea as section[id] on the landing page, with room for the heading's rule. */
.docs-content h2[id],.docs-content h3[id],.docs-content h4[id]{scroll-margin-top:5.5rem}
.docs-content ul,.docs-content ol{margin-bottom:1rem}
/* ── "On this page" jump nav (long docs pages only - pageJumpNav) ─────────────
   Bottom-right, deliberately quiet: a 2.25rem disc that reads as page furniture
   until you want it. Logical inset so the Arabic build puts it in the corner an RTL
   reader reaches for. Tokens only (--text/--muted/--border/--pale, all redefined by
   .dark) so dark mode needs no second palette here. */
.doc-jump{position:fixed;bottom:1rem;inset-inline-end:1rem;z-index:88}
.doc-jump-btn{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border-radius:999px;border:1px solid var(--border);background:var(--pale);color:var(--muted);cursor:pointer;box-shadow:0 2px 10px #0c322c1f;transition:color .12s,border-color .12s}
.doc-jump-btn svg{width:1.1rem;height:1.1rem}
.doc-jump-btn:hover,.doc-jump-btn[aria-expanded="true"]{color:var(--green);border-color:var(--green)}
/* The first six declarations are RESETS, not choices: the bare nav element selector at
   the top of this sheet IS the site's top bar (fixed, full-width, 3.75rem, flex), and
   it lands on any <nav> on the page. The landing page's quicknav opts out the same
   way. Losing them lays this panel out as a strip across the bottom of the window. */
.doc-jump-nav{position:absolute;display:block;top:auto;width:auto;height:auto;overflow-x:hidden;transition:none;bottom:calc(100% + .5rem);inset-inline-end:0;min-width:14rem;max-width:min(20rem,calc(100vw - 2rem));max-height:min(60vh,26rem);overflow-y:auto;padding:.4rem;background:var(--pale);border:1px solid var(--border);border-radius:10px;box-shadow:0 10px 34px #0c322c26}
.doc-jump-nav[hidden]{display:none}
.doc-jump-title{font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin:.15rem .5rem .35rem}
.doc-jump-nav a{display:block;padding:.32rem .5rem;border-radius:6px;font-size:.875rem;line-height:1.35;color:var(--text);text-decoration:none}
.doc-jump-nav a:hover{background:#30ba7818;color:var(--green);text-decoration:none}
.doc-jump-top{margin-top:.25rem;border-top:1px solid var(--border);padding-top:.45rem;color:var(--muted)}
/* The docs player dock owns this corner while it is open (html.ldp-open, fixed at
   the same 16px). One control per corner - the reader is listening, not scanning. */
html.ldp-open .doc-jump{display:none}
@media(prefers-reduced-motion:reduce){.doc-jump-btn{transition:none}}
@media print{.doc-jump{display:none}}
.docs-content h1{font-size:3rem;color:var(--dark);line-height:1.15;margin-bottom:2rem;padding-bottom:2rem;border-bottom:1px solid var(--border); font-weight:300;}

/* Table */
.table-wrap{overflow-x:auto;margin-bottom:2rem;box-shadow: 0 0 0 1px hsl(var(--border)), 0 .2rem .4rem #00000018; border-radius: 1.5em;}
table{border-collapse:collapse;width:100%;font-size:.875rem}
thead tr th:first-child{border-radius: 1em 0 0 0}
thead tr th:last-child{border-radius: 0 1em 0 0}
th,td{padding:.55rem .9rem;text-align:start;border:1px solid var(--border)}
th{background:var(--pale);font-weight:600;color:var(--dark)}
tr:nth-child(even) td{background:hsl(var(--muted) / 0.4)}

/* Mascots */
.social-proof-mascot{position:absolute;right:4%;top:50%;transform:translateY(-50%);width:clamp(90px,12vw,180px);pointer-events:none;filter:drop-shadow(0 8px 20px rgba(12,50,44,.18))}
.footer-inner{display:flex;align-items:center;justify-content:center;gap:1rem}
.footer-mascot{width:2.75rem;flex-shrink:0;filter:drop-shadow(0 2px 6px rgba(0,0,0,.18))}
@media(max-width:768px){
  .social-proof-mascot{display:none}
}

/* Social proof */
.social-proof{padding:4rem 0 3rem;background:hsl(var(--background));overflow:hidden;position:relative}
.social-proof-inner{text-align:center;padding:0 1.5rem 2.5rem;max-width:50rem;margin:0 auto}
.social-proof h2{font-size:2rem;color:var(--dark);margin-bottom:.375rem}
.social-proof-date{font-size:.8125rem;color:var(--green);font-weight:600;margin-bottom:.625rem;letter-spacing:.02em;text-transform:uppercase}
.social-proof-desc{color:var(--muted);font-size:.9375rem;line-height:1.6}
/* "Founded by SUSE" badge - same size everywhere it appears (hero, social proof, footer) */
.social-proof-founded{margin:1.5rem 0 0;text-align:center}
.social-proof-credit{text-align:center;color:var(--muted);font-size:.875rem;margin-top:1.75rem;padding:0 1.5rem}
.social-proof-credit a{color:var(--green);font-weight:600;text-decoration:none}
.social-proof-credit a:hover{text-decoration:underline}

.opensource-section{padding:5rem 2rem;background:var(--pale);text-align:center}
.opensource-inner{max-width:720px;margin:0 auto}
.opensource-section h2{margin-bottom:1.25rem}
.opensource-section p{color:var(--muted);font-size:1.0625rem;line-height:1.8}

.quokka{max-width:320px;}
@media(max-width:768px){.quokka{max-height:260px;width:auto;max-width:60vw}}
/* Footer */
footer{border-top:1px solid var(--border);padding:2rem 1.5rem;text-align:center;color:var(--muted);font-size:.8125rem;background:var(--pale)}
footer a{color:var(--muted);text-decoration:underline}
footer a:hover{color:var(--dark)}
footer .founded-badge{margin-top:.5rem}
/* Footer sitemap - the whole docs set, ten columns (see FOOTER_SECTIONS).
   auto-fit is right for a handful of columns and wrong for ten: it maximises the
   count, so 1180px yields seven and the last three sit alone on a second row under
   four empty tracks. Explicit counts instead - 2 on a phone, 3 on a tablet, then 5.
   Ten divides by both 2 and 5, so the phone and the desktop layouts are exactly
   full (5 rows of two; 2 rows of five). The tablet band is the one that cannot be:
   ten in threes leaves a single column on a fourth row, and the alternative (four
   columns, 4+4+2) trades that for a half-empty row at a narrower column width.
   align-items:start keeps a short column's links at the top of its row
   rather than stretched down it. Columns read left-aligned inside a centred footer,
   which is what makes them scannable as lists rather than as prose. Titles take
   var(--text), not var(--dark), because --dark keeps its value in the dark theme
   and would go invisible there. */
.footer-sitemap{display:grid;grid-template-columns:repeat(2,1fr);align-items:start;gap:1.25rem 1.5rem;max-width:1180px;margin:0 auto 1.75rem;padding-bottom:1.75rem;border-bottom:1px solid var(--border);text-align:start}
@media(min-width:34rem){.footer-sitemap{grid-template-columns:repeat(3,1fr)}}
@media(min-width:64rem){.footer-sitemap{grid-template-columns:repeat(5,1fr)}}
.footer-sitemap a{display:flex;align-items:flex-start;gap:.45em;color:var(--muted);text-decoration:none;padding:.15rem 0 .15rem;line-height:2}
.footer-sitemap a:hover{color:var(--green);text-decoration:underline}
/* Every sitemap link opens with the SAME glyph the docs sidebar gives that page
   (SIDEBAR_ICON - one page→icon mapping, both navs), so the landmark a reader
   learned on the rail keeps working down here. Decorative: aria-hidden spans,
   sized in em to the footer's own text so rows and the smaller uppercase headings
   each get a matching icon from one rule. margin-top holds the 1.5em glyph on the
   FIRST line of the 2-line-height row when a label wraps. */
.footer-sitemap .sitemap-ic{flex:none;width:1.5em;height:1.5em;margin-top:.22em;opacity:.6;color:var(--green)}
.footer-sitemap .sitemap-ic svg{width:100%;height:100%;display:block}
.footer-sitemap a:hover .sitemap-ic{opacity:1}
/* The column heading is a LINK to its pathway's main page. That is what pays for
   the full enumeration: the overview never costs a row of its own, and the two or
   three columns a long pathway is split across all point their heading at the same
   hub. It keeps the heading's own weight and colour rather than the muted link
   treatment two rules above - declared AFTER them so it wins without a specificity
   fight - and takes the underline only on hover, so it reads as a heading first and
   a destination second. footer a{text-decoration:underline} is the rule overridden. */
.sitemap-title{font-size:.6875rem;text-transform:uppercase;letter-spacing:.1em;color:var(--text);font-weight:700;margin-bottom:.5rem;text-decoration:none}
.footer-sitemap a.sitemap-title{color:var(--text)}
.footer-sitemap a.sitemap-title:hover{color:var(--green);text-decoration:underline}
.sitemap-title .sitemap-ic{ width:2em; height:2em; color:var(--text);}

/* Hamburger */
.nav-hamburger{display:none;background:none;border:none;cursor:pointer;color:hsl(var(--on-band-dark) / .65);width:2.25rem;height:2.25rem;align-items:center;justify-content:center;border-radius:5px;padding:.3rem;flex-shrink:0}
.nav-hamburger:hover{color:hsl(var(--on-band-dark));background:rgba(255,255,255,.1)}
.nav-hamburger svg{width:1.25rem;height:1.25rem;pointer-events:none}
.nav-hamburger .icon-close{display:none}
.nav-hamburger.open .icon-menu{display:none}
.nav-hamburger.open .icon-close{display:block}
/* The panel scrolls on its own: below 768px it also carries the page nav (see
   .nav-mobile-page), which on a builders page is longer than a phone screen.
   overscroll-behavior keeps that scroll from continuing into the article behind it. */
.nav-mobile-menu{display:none;position:fixed;top:3.75rem;left:0;right:0;background:hsl(var(--band-dark));border-bottom:1px solid rgba(255,255,255,.1);padding:1rem 1.5rem 1.5rem;z-index:99;flex-direction:column;gap:.125rem;max-height:calc(100vh - 3.75rem);overflow-y:auto;overscroll-behavior:contain}
.nav-mobile-menu.open{display:flex}
.nav-mobile-menu a{color:hsl(var(--on-band-dark) / .7);font-size:.9375rem;padding:.625rem .625rem;border-radius:6px;display:block;text-decoration:none}
.nav-mobile-menu a:hover{color:hsl(var(--on-band-dark));background:rgba(255,255,255,.07)}
.nav-mobile-menu a.active{color:var(--green);font-weight:600}
.nav-mobile-menu .nav-launch{background:hsl(var(--band-accent));color:hsl(var(--band-dark))!important;font-weight:700;text-align:center;margin-top:.75rem;padding:.75rem;border-radius:8px}
.nav-mobile-menu .nav-launch:hover{background:hsl(var(--band-accent) / .82)}
/* Page nav inside the hamburger panel. Hidden by default and switched on at 768px
   only: from 768 to 1100px the hamburger is open for business while the rail is
   still on screen, and listing the same links twice would be noise. The rule sits
   with the other panel styles rather than in the media query so the two kinds of
   navigation are described in one place. */
.nav-mobile-page{display:none;margin-top:.75rem;padding-top:.75rem;border-top:1px solid rgba(255,255,255,.14)}
.nav-mobile-title{color:var(--green);font-size:.8125rem;font-weight:700;letter-spacing:.02em;padding:0 .625rem .25rem}
/* .55 not .42 - at 42% over the panel's #0c322c this computes to 3.7:1, under AA
   for 11px text. .55 clears 5.3:1 and still reads as a quieter tier than the
   links at .7. */
.nav-mobile-label{font-size:.6875rem;text-transform:uppercase;letter-spacing:.1em;color:hsl(var(--on-band-dark) / .55);font-weight:700;margin:.75rem 0 .125rem;padding:0 .625rem}

/* Mobile */
@media(max-width:900px){
  .platform-whats-wrap{flex-direction:column}
  .whats-label{display:none}
  .platform-section{padding:4rem 2rem}
  .whats-a-tool{padding:4rem 2rem}
  .platform-inner,.whats-inner{max-width:760px;margin:0 auto}
  .tool-lead{max-width:640px;margin:0 auto 2rem}
  .tool-anatomy{max-width:720px;margin:0 auto 2rem}
  .platform-features{grid-template-columns:repeat(2,1fr)}
}
/* Collapse the top nav to a hamburger before its links overflow into a horizontal
   scroll. The full link row needs ~1032px; collapse at 1100px for a cross-browser /
   font-fallback margin. (The docs grid + content keep reflowing at 768px below.) */
@media(max-width:1100px){
  nav{overflow-x:visible}
  /* Collapse the desktop nav links into the hamburger - but NOT the search-result
     anchors, which are also <a> inside <nav> (the results panel lives in .docs-search).
     Without the exemption this rule hid every hit, collapsing the results panel to an
     empty strip on any viewport ≤1100px, and neither the jump nav's section links
     (.doc-jump-nav), for the same reason. */
  nav:not(.quicknav):not(.doc-jump-nav) a:not(.brand):not(.docs-search-hit){display:none}
  nav .nav-group{display:none}
  .nav-hamburger{display:flex}
}
@media(max-width:768px){
  .docs-wrap{grid-template-columns:1fr}
  /* The rail goes away rather than stacking above the article: as a static block it
     put a screenful of nav in front of the first sentence of every short page. Its
     links reappear inside the hamburger panel (.nav-mobile-page), which is switched
     on by the same breakpoint. */
  .docs-sidebar{display:none}
  .nav-mobile-page{display:block}
  /* Top padding must still clear the 3.75rem FIXED nav - collapsing it with the
     side padding slid every page's h1 underneath the bar on phones. */
  .docs-content{padding:1.75rem 1rem 1.5rem}
  .docs-content.no-mast{padding-top:5.25rem}
  .audience-card{
    --aud-card-display:flex;
    display:flex;flex-direction:column;
    gap:2rem;padding:2.5rem 1.25rem;
  }
  .audience-header{padding:3rem 1rem 1.25rem}
  .audience-title{font-size:1.875rem}
  .audience-tabs{gap:.375rem;padding:.625rem .75rem .875rem}
  .audience-tab{padding:.4rem .7rem}
  .tool-anatomy{gap:.5rem}
  .tool-plus{display:none}
  .tool-part{min-width:110px}
}
@media(max-width:480px){
  .platform-features{grid-template-columns:1fr}
  .tool-features{grid-template-columns:1fr}
  .card-benefits{grid-template-columns:1fr}
  .try-now-callout{position:static;transform:none;width:auto;margin-top:1.75rem;flex-direction:column;align-items:stretch}
  .try-now-callout .btn{text-align:center;justify-content:center}
}



/* Theme toggle */
.nav-theme-toggle{background:none;border:none;cursor:pointer;color:hsl(var(--on-band-dark) / .65);width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;border-radius:5px;padding:.25rem;flex-shrink:0;margin-left:.25rem}
.nav-theme-toggle:hover{color:hsl(var(--on-band-dark));background:rgba(255,255,255,.1)}
.nav-theme-toggle svg{width:1.1rem;height:1.1rem;pointer-events:none}
/* Show the ACTIVE theme's glyph. Default (light, incl. no [data-theme]) = sun;
   dark = moon; brand = palette. Each theme hides the other two. */
.nav-theme-toggle .icon-moon,.nav-theme-toggle .icon-brand{display:none}
.nav-theme-toggle .icon-sun{display:block}
[data-theme="dark"] .nav-theme-toggle .icon-sun{display:none}
[data-theme="dark"] .nav-theme-toggle .icon-moon{display:block}
[data-theme="brand"] .nav-theme-toggle .icon-sun{display:none}
[data-theme="brand"] .nav-theme-toggle .icon-brand{display:block}

/* Dark mode. The token redefinitions that used to live here are gone: the DOCS_BRIDGE
   above maps --text/--muted/--border/--pale/--page onto the app's [data-theme]-driven
   slots, so dark mode falls out of tokens.css. The component rules below only restyle
   the few places that carry a hardcoded colour of their own. */
[data-theme="dark"] body{background:var(--page)}
[data-theme="dark"] .social-proof{background:hsl(var(--background))}
[data-theme="dark"] .social-proof h2{color:var(--text)}
[data-theme="dark"] .social-proof-desc{color:var(--muted)}
[data-theme="dark"] tr:nth-child(even) td{background:hsl(var(--muted) / 0.4)}
[data-theme="dark"] footer{border-top-color:var(--border)}
[data-theme="dark"] .docs-content h1,[data-theme="dark"] .docs-content h2,[data-theme="dark"] .docs-content h3{color:var(--text)}
[data-theme="dark"] th{color:var(--text)}
/* Code on a dark ground (dark AND brand - brand is a dark-teal theme with no
   [data-theme="brand"] overrides of its own, so it inherits the base rules; the
   base pre now uses hsl(var(--foreground)) so it is already legible, and these
   add the dark box + border for parity). Give inline code a dark surface + light
   text, and the pre block a dark box. The last rule keeps code inside pre
   background-free - [data-theme="dark"] .docs-content code would otherwise
   out-specify the base "pre code background none" reset. */
[data-theme="dark"] .docs-content code,[data-theme="brand"] .docs-content code{background:hsl(var(--muted));color:var(--text)}
[data-theme="dark"] .docs-content pre,[data-theme="brand"] .docs-content pre{background:hsl(var(--muted));color:var(--text);border:1px solid var(--border)}
/* The Warde page sets its two verse blocks as an inscription rather than as code.
   Scoped to the page so no other fenced block is touched. Centred and letterspaced
   because that is what the 1932 broadside and the 1940 bronze both do - the poem was
   cut in capitals for a titling face, and reading it as a listing loses the shape. */
.page-beatrice-warde .docs-content pre{font-family:'Cinzel',Georgia,serif;font-size:1.0625rem;line-height:2.05;letter-spacing:.055em;text-align:center;background:linear-gradient(#fbfaf7,#f4f2ec);color:#25313a;padding:2.5rem 1.5rem;border-radius:10px;box-shadow:inset 0 0 0 1px #0000000f,0 1px 2px #0000000a;white-space:pre-wrap;text-wrap:balance}
.page-beatrice-warde .docs-content pre code{font-family:inherit;font-size:inherit;background:none;padding:0}
[data-theme="dark"] .page-beatrice-warde .docs-content pre,[data-theme="brand"] .page-beatrice-warde .docs-content pre{background:linear-gradient(#12271d,#0d2016);color:#e8f0ea;box-shadow:inset 0 0 0 1px #ffffff14}
.doc-audio{margin:0 0 .5rem;padding:0}
.doc-audio audio{width:100%;height:40px;display:block}
/* An audiogram MP4 is square (1080²) and would swamp the column at full width -
   cap it and centre it, letting its own aspect ratio set the height. The dark
   fill matches the audiogram's own background so the poster-load gap isn't black. */
.doc-video{margin:0 auto 1rem;max-width:min(420px,100%)}
.doc-video video{width:100%;height:auto;display:block;border-radius:10px;background:#0d1f17}
[data-theme="dark"] .docs-content pre code{background:none;color:inherit}
/* ── Pilot / prototype disclaimer badge (in the dark hero) ─────────────────── */
.hero-pilot{display:inline-flex;align-items:center;gap:.5rem;margin-bottom:3rem;padding:.34rem .36rem .34rem .55rem;background:rgba(254,124,63,.17);border-radius:999px;text-decoration:none;font-size:.8125rem;color:#ffd9c4;transition:background .15s}
.hero-pilot:hover{background:rgba(254,124,63,.26)}
.hero-pilot-tag{background:var(--orange);color:#2a0f04;font-weight:800;text-transform:uppercase;letter-spacing:.06em;font-size:.66rem;padding:.22em .62em;border-radius:999px}
.hero-pilot-text{padding-right:.35rem}
@media(max-width:600px){.hero-pilot-text{font-size:.74rem}}

/* RTL correctness (Arabic pages get dir="rtl" on <html>): code is Latin and
   always reads LTR - isolate it so surrounding RTL prose doesn't scramble
   leading/trailing punctuation. Mirrors the SPA's parts/rtl.css. */
[dir="rtl"] pre,[dir="rtl"] code,[dir="rtl"] kbd,[dir="rtl"] samp{direction:ltr;text-align:left;unicode-bidi:isolate}
/* The nav row mirrors under RTL, putting the lang FAB toward the LEFT edge -
   follow it with the menu (which is otherwise pinned right:1.5rem physically). */
[dir="rtl"] .lang-menu{right:auto;left:1.5rem}