/*
 * happyhotel case — layout, typography and components
 *
 * Everything that is not a token: resets, the sticky top bar with its
 * progress rail, the chapter navigation, the type scale, the glossary
 * underline and its popover, all card/stat/flow/model components and the
 * responsive breakpoints. Consumes the variables from tokens.css, which
 * loads first.
 */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);
  font-size:16.5px;line-height:1.56;letter-spacing:-.006em;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  transition:background .25s ease,color .25s ease;
  padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);
}
img{max-width:100%;height:auto;display:block}
[hidden]{display:none!important}
a{color:inherit}
::selection{background:var(--accent-soft)}

/* ── top bar ──
   Frost sits on ::before, not on .top itself. Sticky plus an opaque fill on the
   same element flattens backdrop-filter, which is why the glass looked gone:
   the bar painted 88% --bg and never sampled the page scrolling under it.
   isolation keeps the z-index:-1 plate inside the bar, in front of the page.
   min-height:55px keeps the original two-line brand height after the subtitle
   came out, so the fixed rail at top:104px still sits on the same line. */
.top{position:sticky;top:env(safe-area-inset-top,0px);z-index:40;isolation:isolate;
  border-bottom:1px solid var(--line)}
.top::before{content:"";position:absolute;inset:0;z-index:-1;
  background:var(--glass-fill);
  -webkit-backdrop-filter:var(--glass-filter);backdrop-filter:var(--glass-filter)}
.top__in{max-width:1180px;margin:0 auto;padding:11px 24px;min-height:55px;display:flex;align-items:center;gap:16px}
.brand{font-weight:600;font-size:14.5px;line-height:1.15;letter-spacing:-.015em;white-space:nowrap;min-width:0;overflow:hidden;text-overflow:ellipsis}
.top__sp{flex:1;min-width:8px}
@media(max-width:620px){
  .top__in{padding:10px 16px;gap:10px;min-height:0}
  .ctl:has([data-lang]) button{padding:0 8px;font-size:11px}
}
.ctl{display:inline-flex;align-items:stretch;height:32px;box-sizing:border-box;
  border:1px solid var(--line);border-radius:7px;overflow:hidden;background:var(--raised);position:relative}
.ctl button{appearance:none;border:0;background:transparent;color:var(--muted);font:500 11.5px/1 var(--mono);
  letter-spacing:.06em;padding:0 12px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  height:100%;transition:color .22s cubic-bezier(.4,0,.2,1)}
.ctl button[aria-pressed="true"],.ctl button.on{color:var(--ink)}
.ctl button:hover{color:var(--ink)}
.ctl:has([data-lang]) button{flex:1;background:transparent;position:relative;z-index:1}
.ctl:has([data-lang]) button[aria-pressed="true"],
.ctl:has([data-lang]) button.on{background:transparent;color:var(--ink)}
.ctl:has([data-lang])::before{content:"";position:absolute;z-index:0;pointer-events:none;
  top:2px;bottom:2px;left:2px;width:calc(50% - 2px);border-radius:5px;background:var(--accent-soft);
  transform:translate3d(0,0,0);transition:transform .22s cubic-bezier(.4,0,.2,1)}
html[lang="en"] .ctl:has([data-lang])::before{transform:translate3d(100%,0,0)}
@media(prefers-reduced-motion:reduce){
  .ctl:has([data-lang])::before,.ctl button,.wrap,footer{transition:none}
}
.wrap,footer{transition:opacity .12s cubic-bezier(.4,0,.2,1)}
html.is-langing .wrap,
html.is-langing footer,
html.is-langing .kbd{opacity:.38}
.ctl:not(:has([data-lang])){width:32px;flex:none}
.ctl:not(:has([data-lang])) button{width:100%;padding:0}
.ctl button svg,.ico{display:block;width:14px;height:14px;flex:none;
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.ico-sheet{position:absolute;width:0;height:0;overflow:hidden}
#themebtn{position:relative}
#themebtn .ico{position:absolute;left:50%;top:50%;margin:-7px 0 0 -7px;
  transition:opacity .7s cubic-bezier(.18,.92,.22,1),transform .7s cubic-bezier(.18,.92,.22,1)}
#themebtn .i-sun{opacity:1;transform:translate(0,0) scale(1)}
#themebtn .i-moon{opacity:0;transform:translateY(8px)}
html[data-theme="dark"] #themebtn .i-sun{opacity:0;transform:translate(5px,-6px) scale(.55)}
html[data-theme="dark"] #themebtn .i-moon{opacity:1;transform:translateY(0)}
@media(prefers-reduced-motion:reduce){
  #themebtn .ico{transition:none}
}

/* Theme wash: moon rises from the bottom into dark; sun opens from the
   top-right control into light. Old frame stays put; the new one clips over it.
   Duration lives on the group too — the UA default is 250ms and would clip this. */
::view-transition-group(root){animation-duration:.85s;animation-timing-function:cubic-bezier(.18,.92,.22,1)}
::view-transition-old(root){animation:none;z-index:1;mix-blend-mode:normal}
::view-transition-new(root){z-index:2;mix-blend-mode:normal;
  animation:theme-moon .85s cubic-bezier(.18,.92,.22,1) both}
html.theme-to-light::view-transition-new(root){animation-name:theme-sun}
@keyframes theme-moon{
  from{clip-path:circle(0 at 50% 118%)}
  to{clip-path:circle(140vmax at 50% 52%)}
}
@keyframes theme-sun{
  from{clip-path:circle(0 at var(--sun-x,94%) var(--sun-y,8%))}
  to{clip-path:circle(140vmax at 58% 44%)}
}
html.theme-to-dark body,html.theme-to-light body{transition:none}
@media(prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none!important}
}
.prog{position:absolute;left:0;bottom:-1px;height:2px;background:var(--accent);width:0;transition:width .12s linear}

/* ── layout ──
   The wrap constrains nothing any more. It is a full-width positioning context
   so the section bands can span the window while the rail floats in the left
   gutter; the content column moved one level down into .shell. */
.wrap{position:relative}

/* Content column, shared by every section and the hero. Below the rail
   breakpoint it is simply centred. From 1120px the rail takes 248px plus a 56px
   gap on the left and rail plus content are centred together as one 1180px
   block. Margins rather than a max-width define the width, so the column
   shrinks with the viewport at 1120px and settles on 828px from 1180px upward —
   the same geometry the old grid produced, but without owning the background. */
.shell{margin-inline:auto;max-width:876px;padding-inline:24px}
@media(min-width:1120px){
  .shell{max-width:none;
    margin-inline:calc(max(0px,(100% - 1180px)/2) + 304px) max(0px,(100% - 1180px)/2)}
}

/* The rail is a fixed chapter index in the left gutter — it does not
   travel with the page. No plate: links sit on the band, the divider
   crosses freely. pointer-events only on the inner stack so the track
   does not swallow clicks. top:104px docks it under the sticky topbar. */
.rail{display:none}
@media(min-width:1120px){
  .rail{display:block;position:fixed;z-index:30;
    top:104px;left:calc(max(0px,(100% - 1180px)/2) + 24px);
    width:var(--rail);pointer-events:none}
  .rail__in{padding:14px 8px 16px;pointer-events:auto}
}
.rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px}
.rail a{display:flex;gap:11px;align-items:baseline;text-decoration:none;color:var(--muted);
  font-size:13.5px;line-height:1.35;padding:7px 10px 7px 12px;border-left:2px solid transparent;border-radius:0 6px 6px 0;
  transition:color .18s,border-color .18s,background .18s}
.rail a:hover{color:var(--ink);background:var(--accent-soft)}
.rail a[aria-current="true"]{color:var(--ink);border-left-color:var(--accent);font-weight:500}
.rail .n{font:500 10.5px/1.6 var(--mono);color:var(--muted);opacity:.75;min-width:16px}
.rail a[aria-current="true"] .n{color:var(--accent);opacity:1}
.rail h6{margin:0 0 12px 12px;font:500 10.5px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
.rail__read{margin:14px 0 0 12px;display:flex;align-items:center;gap:5px;
  font:400 11px/1.4 var(--mono);color:var(--muted);opacity:.55}
.rail__read .ico{width:12px;height:12px}

main{min-width:0}
section{scroll-margin-top:96px}
.col{max-width:var(--maxw)}

/* Section bands. A full-width hairline divider carries the rhythm and keeps
   the focus on one section at a time; the divider runs the whole window,
   including behind the rail. The surface itself is one --bg throughout.
   Replaces the former .sec-gap spacers, whose 80px are now the bands' padding. */
.band{border-bottom:1px solid var(--line);padding-block:80px}
@media(min-width:768px){.band{padding-block:120px}}
/* Hairline above 01 — editorial close after the hero gap, not a landing CTA.
   Top padding only: keep the band's bottom padding so 01→02 is unchanged. */
#start{border-top:1px solid var(--line);padding-top:40px}

/* Section stack. Direct children of the shell (copy column, figure, grid) sit
   on a generous gap so chapters read as composed blocks, not a packed list.
   Inside a column, copy stays tighter; modules open up from the text. */
.band>.shell{display:flex;flex-direction:column;gap:48px}
@media(min-width:768px){.band>.shell{gap:56px}}
.band>.shell>*{margin-block:0}
.band .col>h2{margin-bottom:24px}
.band .col>.eyebrow{margin-bottom:12px}
.band .col>p{margin-bottom:20px}
.band .col>h3{margin-bottom:10px}
.band .col>h3+p{margin-top:0;margin-bottom:20px}
.band .col>:last-child{margin-bottom:0}
.band .col>:is(.grid2,.grid3,.plist,.model,.flow,.bands,.ledger,.xfer,.dobj,.bento,.callout){margin-top:16px}
.band .col>:is(.grid2,.grid3,.plist,.model,.flow,.bands,.ledger,.xfer,.dobj,.bento,.callout)+ :is(p,h3,.callout,.model,.xfer){margin-top:36px}
.band .col>.plist+*{margin-top:44px}
.band .col>.model+h3{margin-top:44px}
.band .callout{margin-block:0}
.band .col>blockquote{margin:36px 0}
.band .col>p.mt:has(+.flow){margin-bottom:16px}
.band .col>:is(.flow,.dobj)+p.xs{margin-top:20px}


/* ── type ── */
h1{font-size:clamp(34px,6vw,58px);line-height:1;letter-spacing:-.04em;font-weight:650;margin:0 0 22px}
h2{font-size:clamp(25px,3.4vw,36px);line-height:1.1;letter-spacing:-.03em;font-weight:620;margin:0 0 18px;max-width:28ch;-webkit-text-wrap:balance;text-wrap:balance}
h3{font-size:17px;line-height:1.35;letter-spacing:-.016em;font-weight:600;margin:0 0 7px}
h4{font-size:14px;line-height:1.4;letter-spacing:-.01em;font-weight:600;margin:0 0 5px}
p{margin:0 0 17px}
.lead{font-size:18.5px;line-height:1.5;color:var(--ink);letter-spacing:-.012em}
.mut{color:var(--muted)}
.sm{font-size:14px;line-height:1.5}
.xs{font-size:12.5px;line-height:1.5;color:var(--muted)}
strong{font-weight:600}

/* Hero kicker: same accent as chapter preheaders, no 22px dash. */
.hero .kicker{font:500 11px/1 var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent);margin:0 0 20px}
.eyebrow{font:500 11px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--accent);margin:0 0 9px}

/* inline term chips (non-glossary). Glossary overrides below.
   --tag-fill sits a step above --bg so chips lift on the page and on --raised.
   On accent-soft cards the fill stays transparent so the blue shows through.
   Size tracks the surrounding sentence; line-height:1 plus a small drop keeps Geist Mono on Inter. */
.t{display:inline;font-family:var(--mono);font-size:.9em;line-height:1;
  letter-spacing:-.005em;padding:.06em .32em .08em;border-radius:5px;white-space:nowrap;
  border:1px solid var(--line);background:var(--tag-fill);color:var(--ink);
  vertical-align:-.08em;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  transition:box-shadow .17s ease,border-color .17s ease}
.t.v{border-color:color-mix(in srgb,var(--accent) 30%,var(--line));
  background:var(--accent-soft);color:color-mix(in srgb,var(--accent) 72%,var(--ink))}
html[data-theme="dark"] .t.v{color:var(--accent)}
h2 .t:not([data-term]),h3 .t:not([data-term]),h4 .t:not([data-term]){font-size:.86em;padding:.05em .3em}
.callout .t:not(.v),
.bento>div.accent .t:not(.v),
.model__bd>div.accent .t:not(.v),
.flow .st.gate .t:not(.v){background:transparent}

.t[data-term]{cursor:help}
/* Glossary trigger in running copy — editorial dotted underline, not a chip. */
.inline-term,
.t[data-term]:not(.tag),
html[data-theme="dark"] .t[data-term]:not(.tag){
  display:inline;
  font-family:inherit;font-size:inherit;font-weight:inherit;font-style:inherit;
  line-height:inherit;letter-spacing:inherit;color:inherit;
  vertical-align:baseline;margin:0;padding:0;border:0;border-radius:0;
  background:transparent;box-shadow:none;white-space:inherit;
  text-decoration:underline;text-decoration-style:dotted;
  text-decoration-thickness:1px;text-underline-offset:.18em;
  text-decoration-color:var(--muted);
  transition:text-decoration-color .15s ease,background-color .15s ease}
.t[data-term]:not(.tag):hover,
.t[data-term]:not(.tag):focus-visible{
  text-decoration-color:var(--accent);background:transparent}
.t[data-term]:not(.tag).on{
  text-decoration-color:var(--accent);background:var(--accent-soft)}
.t[data-term]:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tag.t[data-term]:hover,.tag.t[data-term]:focus-visible,.tag.t[data-term].on{
  border-color:color-mix(in srgb,var(--accent) 52%,var(--line));
  box-shadow:0 3px 9px -2px color-mix(in srgb,var(--accent) 34%,transparent),
             0 1px 2px color-mix(in srgb,var(--ink) 8%,transparent)}

/* inline-term annotation — hug the trigger, not a floating card.
   Title is a line of type in the same padding box, not a header band. */
#tip{position:fixed;z-index:60;width:max-content;min-width:200px;max-width:264px;
  padding:13px 15px;border-radius:9px;border:1px solid var(--line);background:var(--raised);
  box-shadow:var(--lift);pointer-events:none;
  opacity:0;transform:translateY(2px);
  transition:opacity .14s ease,transform .14s ease}
#tip.on{opacity:1;transform:translateY(0);pointer-events:auto}
.tip__k{display:block;margin:0 0 8px;
  font:500 11px/1.2 var(--mono);letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent)}
.tip__bd{margin:0;font-size:13.5px;line-height:1.45;color:var(--muted)}
.tip__bd ul{margin:6px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px}
.tip__bd li{position:relative;padding-left:10px;line-height:1.42}
.tip__bd li::before{content:"";position:absolute;left:1px;top:6px;width:3px;height:3px;
  border-radius:50%;background:var(--accent);opacity:.55}
.tip__bd li b{display:inline;font-family:var(--sans);font-size:13.5px;letter-spacing:0;
  text-transform:none;color:var(--ink);font-weight:600;margin:0}
@media(prefers-reduced-motion:reduce){
  .t,#tip{transition:opacity .12s ease}
  #tip,#tip.on{transform:none}
}
@media print{#tip{display:none}}

hr.rule{border:0;border-top:1px solid var(--line);margin:0}

/* ── hero ──
   Top padding steps onto the 80px band used by hero-bottom / old sec-gap, so
   the title block has more air under the topbar. The rail is fixed under the
   topbar and no longer shares the kicker line. Bottom padding is only the
   editorial gap onto the #start hairline — not a second band. */
.hero{padding:80px 0 56px}
@media(min-width:768px){.hero{padding:80px 0 56px}}
@media(max-width:700px){.hero{padding:72px 0 48px}}
.hero .lead{max-width:60ch}
/* Schematic platform window between lead and metagrid — same 828px shell
   as the meta rail. Decorative chrome is aria-hidden; mkCap is the sr label.
   Beats later figure{margin:30px 0} via the .hero ancestor. */
.hero figure.mock{margin:32px 0 0}
.mock__win{border:1px solid var(--line);border-radius:12px;background:var(--raised);
  overflow:hidden;box-shadow:var(--lift)}
.mock__chrome{display:flex;align-items:center;gap:6px;padding:9px 13px;
  border-bottom:1px solid var(--line);background:var(--bg)}
.mock__chrome>i{width:7px;height:7px;border-radius:50%;background:var(--line);flex:none}
.mock__app{margin-left:8px;font:500 10px/1 var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.mock__search{margin-left:auto;width:min(190px,34%);height:16px;border-radius:8px;
  border:1px solid var(--line);background:var(--raised)}
.mock__body{display:flex}
.mock__rail{display:flex;flex-direction:column;gap:9px;padding:15px 13px;
  border-right:1px solid var(--line);flex:none}
.mock__rail b{width:16px;height:5px;border-radius:2px;background:var(--line);display:block}
.mock__rail b.on{background:var(--accent-mark)}
.mock__queue{flex:none;width:34%;max-width:190px;padding:17px 14px;
  border-right:1px solid var(--line)}
.mock__qi{border:1px solid var(--line);border-radius:7px;padding:9px 10px;
  margin-bottom:8px;background:var(--bg)}
.mock__qi.on{border-color:var(--accent-line);background:var(--accent-soft)}
.mock__qi span{display:block;height:5px;border-radius:3px;background:var(--line)}
.mock__qi span:first-child{width:78%;margin-bottom:5px}
.mock__qi span:last-child{width:52%}
.mock__qi.on span{background:var(--accent-line)}
.mock__main{padding:17px 18px 19px;flex:1;min-width:0}
.mock__lb{margin:0 0 8px;font:500 9.5px/1 var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.mock__ln{height:6px;border-radius:3px;background:var(--line);margin-bottom:7px}
.mock__ln--a{width:64%}.mock__ln--b{width:41%}.mock__ln--c{width:88%}
.mock__ln--d{width:72%}.mock__ln--e{width:44%}
.mock__sep{height:1px;background:var(--line);margin:14px 0 13px}
.mock__conf{display:flex;align-items:center;gap:10px;margin-top:13px}
.mock__conf .mock__lb{margin:0}
.mock__steps{display:flex;gap:3px}
.mock__steps i{width:16px;height:4px;border-radius:2px;background:var(--line)}
.mock__steps i.on{background:var(--accent)}
.mock__gate{display:flex;align-items:center;gap:7px;margin-top:15px;flex-wrap:wrap}
.mock__btn{font:500 9.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--line);border-radius:6px;padding:6px 10px}
.mock__btn--p{color:var(--accent);border-color:var(--accent-line);background:var(--accent-soft)}
.mock__gl{margin-left:4px;font:400 9.5px/1 var(--mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);opacity:.65}
.mock__chat{flex:none;width:24%;max-width:148px;padding:12px 10px 10px;
  border-left:1px solid var(--line);background:var(--raised);
  display:flex;flex-direction:column;gap:6px}
.mock__chat>.mock__lb{opacity:.55;margin:0 0 2px;letter-spacing:.08em}
.mock__thread{display:flex;flex-direction:column;gap:6px;flex:1;min-height:0}
.mock__msg,.mock__dcard{flex:none}
.mock__msg{display:flex;flex-direction:column;gap:4px;max-width:86%;
  padding:7px 8px}
.mock__msg span{display:block;height:4px;border-radius:2px;background:var(--line)}
.mock__msg span:last-child{width:62%}
.mock__msg--in{align-self:flex-start;background:var(--bg);border:1px solid var(--line);
  border-radius:7px 7px 7px 2px}
.mock__msg--out{align-self:flex-end;background:var(--bg);border:1px solid var(--line);
  border-radius:7px 7px 2px 7px}
.mock__msg--out span{width:74%}
.mock__dcard{display:flex;flex-direction:column;align-items:flex-start;gap:5px;
  max-width:92%;padding:8px;border:1px solid var(--line);border-radius:7px;
  background:var(--bg)}
.mock__dcard-k{display:block;height:4px;width:38%;border-radius:2px;background:var(--muted);opacity:.45}
.mock__dcard-l{display:block;height:4px;width:92%;border-radius:2px;background:var(--line)}
.mock__dcard-l--s{width:56%}
.mock__dcard .mock__steps{margin-top:1px}
.mock__dcard .mock__steps i{width:11px;height:3px}
.mock__dcard .mock__btn{padding:4px 7px}
.mock__composer{margin-top:auto;height:14px;border-radius:7px;
  border:1px solid var(--line);background:var(--bg)}
@media(max-width:620px){.mock__rail,.mock__queue{display:none}.mock__gl{margin-left:0}}
@media(max-width:520px){.mock__chat{display:none}}
/* Hero meta rail — one plate, page fill, hairlines only. No shadow, no
   radius, no hover: three fields, not three cards. Outer edges share the
   mock's 828px shell; first/last cells sit flush so the columns register. */
.metagrid{display:grid;gap:0;margin:32px 0 0;
  border-block:1px solid var(--line);background:var(--bg);border-radius:0}
@media(min-width:720px){.metagrid{grid-template-columns:repeat(3,1fr)}}
.metagrid>div{padding:22px 0}
@media(min-width:720px){
  .metagrid>div{padding:22px 24px}
  .metagrid>div:first-child{padding-left:0}
  .metagrid>div:last-child{padding-right:0}
  .metagrid>div+div{border-left:1px solid var(--line)}
}
@media(max-width:719px){.metagrid>div+div{border-top:1px solid var(--line)}}
.metagrid dt{font:500 10.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin:0 0 8px}
.metagrid dd{margin:0;font-size:13.5px;line-height:1.45;color:var(--ink)}

/* ── blocks ── */
.card{border:1px solid var(--line);border-radius:12px;background:var(--raised);padding:22px 24px;box-shadow:var(--lift);
  position:relative;isolation:isolate;transition:transform .5s cubic-bezier(.18,.92,.22,1)}
.card::after{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--hover-veil);
  opacity:0;pointer-events:none;transition:opacity .5s cubic-bezier(.18,.92,.22,1)}
.card:hover{transform:translateY(-2px)}
.card:hover::after{opacity:1}
.card .eyebrow{margin:0 0 8px}
.card h4{font-size:17px;line-height:1.28;letter-spacing:-.016em;font-weight:600;margin:0}
.card>.sm{margin:12px 0 0;line-height:1.5}
.grid2>.card,.grid3>.card{display:flex;flex-direction:column}
.grid2>.card>:last-child,.grid3>.card>:last-child{margin-top:auto;padding-top:16px}
.grid2{display:grid;gap:20px}
@media(min-width:680px){.grid2{grid-template-columns:1fr 1fr}}
.grid3{display:grid;gap:20px}
@media(min-width:680px){.grid3{grid-template-columns:repeat(3,1fr)}}

.stat{border:1px solid var(--line);border-radius:12px;background:var(--raised);padding:22px 24px;box-shadow:var(--lift);
  position:relative;isolation:isolate;transition:transform .5s cubic-bezier(.18,.92,.22,1)}
.stat::after{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--hover-veil);
  opacity:0;pointer-events:none;transition:opacity .5s cubic-bezier(.18,.92,.22,1)}
.stat:hover{transform:translateY(-2px)}
.stat:hover::after{opacity:1}
.stat .v{font-size:27px;line-height:1.1;letter-spacing:-.028em;font-weight:620;margin-bottom:5px}
.stat .k{font-size:13.5px;line-height:1.45;margin-bottom:9px}
.tag{display:inline-flex;align-items:center;gap:3px;vertical-align:middle;
  font:500 10px/1.3 var(--mono);letter-spacing:.04em;text-transform:uppercase;
  padding:3px 6px;border-radius:5px;border:1px solid var(--line);color:var(--muted);background:var(--tag-fill)}
.tag.warn{color:var(--warn);border-color:color-mix(in srgb,var(--warn) 30%,var(--line));background:var(--warn-soft)}
.tag.ok{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 30%,var(--line));background:var(--ok-soft);font-weight:600}
.tag .ico{width:11px;height:11px;stroke-width:2.5}
.tag.no{color:var(--danger);border-color:color-mix(in srgb,var(--danger) 30%,var(--line));background:var(--danger-soft)}
.tag.acc{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 32%,var(--line));background:var(--accent-soft)}
.tag.t[data-term]{cursor:help}

blockquote{margin:26px 0;padding:0 0 0 22px;border-left:3px solid var(--accent)}
blockquote p{font-size:clamp(25px,3.4vw,36px);line-height:1.22;letter-spacing:-.03em;
  font-weight:620;margin:0 0 14px;color:var(--ink);-webkit-text-wrap:balance;text-wrap:balance}
blockquote cite{font-style:normal;font-size:14px;line-height:1.5;color:var(--muted)}

.shots{display:grid;gap:20px;margin:30px 0}
@media(min-width:760px){.shots{grid-template-columns:1fr 1fr}}
.shots figure{margin:0;display:flex;flex-direction:column}
.shots figcaption{margin-top:9px;font-size:12.5px;line-height:1.5}
.ph{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  aspect-ratio:3/2;border:1px dashed color-mix(in srgb,var(--muted) 42%,var(--line));
  border-radius:11px;background:var(--bg);padding:16px;text-align:center}
.ph span{font:500 11px/1.4 var(--mono);letter-spacing:.06em;color:var(--muted)}
.ph em{font:400 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  font-style:normal;color:var(--warn);border:1px solid color-mix(in srgb,var(--warn) 32%,var(--line));
  background:var(--warn-soft);border-radius:5px;padding:3px 7px}

figure{margin:30px 0}
figure img{border:1px solid var(--line);border-radius:11px;background:var(--raised);box-shadow:var(--lift)}
figure:not(.mock):has(>img){transition:transform .5s cubic-bezier(.18,.92,.22,1)}
figure:not(.mock):has(>img)>img{transition:box-shadow .5s cubic-bezier(.18,.92,.22,1)}
figure:not(.mock):has(>img):hover,
figure:not(.mock):has(>img):focus-within{transform:translateY(-2px)}
figure:not(.mock):has(>img):hover>img,
figure:not(.mock):has(>img):focus-within>img{box-shadow:var(--hover-media)}
@media(prefers-reduced-motion:reduce){
  .card,.stat,figure:not(.mock):has(>img){transform:none;transition:none}
  .card::after,.stat::after,figure:not(.mock):has(>img)>img{transition:none}
}
figure img.zoomable{cursor:pointer;width:100%}
/* Enlarge affordance, bottom-right of the screenshot (not the caption).
   ::before is the plate; ::after is the magnifier, masked so the glyph
   paints --ink and never a literal colour. */
figure:has(>img.zoomable){display:grid;grid-template-columns:minmax(0,1fr)}
.shots figure:has(>img.zoomable){display:grid}
figure:has(>img.zoomable)>img{grid-area:1/1}
figure:has(>img.zoomable)>figcaption{grid-area:2/1}
figure:has(>img.zoomable)::before,
figure:has(>img.zoomable)::after{
  content:"";grid-area:1/1;align-self:end;justify-self:end;pointer-events:none;z-index:1}
figure:has(>img.zoomable)::before{
  width:32px;height:32px;margin:10px;border:1px solid var(--line);border-radius:7px;
  background:var(--raised);box-shadow:var(--lift)}
figure:has(>img.zoomable)::after{
  width:16px;height:16px;margin:18px;background:var(--ink);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3Cpath d='M11 8v6'/%3E%3Cpath d='M8 11h6'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3Cpath d='M11 8v6'/%3E%3Cpath d='M8 11h6'/%3E%3C/svg%3E") center/contain no-repeat}
figure:has(>img.zoomable):hover::before{
  background:color-mix(in srgb,var(--accent) 14%,var(--raised));
  border-color:color-mix(in srgb,var(--accent) 32%,var(--line))}
figcaption{margin-top:14px;font-size:12.5px;line-height:1.52;color:var(--muted)}
figcaption b{color:var(--ink);font-weight:600}
/* .bleed used to cap figures itself, back when they sat in an unbounded grid
   column. The shell now caps the whole column at 828px, so a figure simply fills
   it — the same width the old cap produced at the sizes that mattered. */

/* numbered principle list */
.plist{display:flex;flex-direction:column;gap:0;margin:0;padding:0;border:1px solid var(--line);border-radius:12px;background:var(--raised);overflow:hidden;box-shadow:var(--lift)}
.plist>li{list-style:none;display:grid;grid-template-columns:26px 1fr;gap:16px;padding:20px 22px;align-items:start}
.plist>li+li{border-top:1px solid var(--line)}
.plist .n{display:flex;align-items:center;justify-content:center;width:26px;height:26px;margin-top:1px;
  border:1px solid var(--line);border-radius:7px;background:var(--bg);
  font:500 10.5px/1 var(--mono);letter-spacing:.02em;color:var(--accent)}
.plist p{margin:0;font-size:14px;line-height:1.5;color:var(--muted)}
.plist .src{display:block;margin-top:7px;font:400 11.5px/1.5 var(--mono);color:var(--muted);opacity:.85}

/* flow / pipeline */
.flow{display:grid;gap:12px;margin:8px 0 0}
@media(min-width:760px){.flow{grid-template-columns:repeat(5,1fr);gap:0}}
.flow .st{border:1px solid var(--line);background:var(--raised);padding:14px 15px;border-radius:10px}
@media(min-width:760px){
  .flow .st{border-radius:0;border-left-width:0}
  .flow .st:first-child{border-left-width:1px;border-radius:10px 0 0 10px}
  .flow .st:last-child{border-radius:0 10px 10px 0}
}
.flow .st .n{font:500 10px/1.6 var(--mono);letter-spacing:.08em;color:var(--accent);margin-bottom:6px}
.flow .st h4{margin-bottom:4px}
.flow .st p{margin:0;font-size:12.5px;line-height:1.45;color:var(--muted)}
.flow .st.gate{background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 34%,var(--line))}
@media(min-width:760px){.flow .st.gate{border-left-width:1px}
  .flow{border-radius:10px;box-shadow:var(--lift)}}
@media(max-width:759px){.flow .st{box-shadow:var(--lift)}}

/* 3-column model (autonomy / handoff / layers) */
.model{border:1px solid var(--line);border-radius:12px;background:var(--raised);overflow:hidden;margin:6px 0 0;box-shadow:var(--lift)}
.model__hd{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;
  padding:12px 18px;border-bottom:1px solid var(--line);background:var(--bg)}
/* Small mono label — card chrome and the flow heading share this. */
.mt{font:500 11px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.model__bd{display:grid;gap:0}
@media(min-width:700px){.model__bd{grid-template-columns:repeat(3,1fr)}}
.model__bd>div{padding:20px 20px}
.model__bd>div>.eyebrow{font-size:10px;letter-spacing:.1em}
@media(min-width:700px){.model__bd>div+div{border-left:1px solid var(--line)}}
@media(max-width:699px){.model__bd>div+div{border-top:1px solid var(--line)}}
.model ul{margin:9px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:5px}
.model ul li{font-size:14px;line-height:1.45;color:var(--muted);padding-left:14px;position:relative}
.model ul li::before{content:"";position:absolute;left:0;top:8px;width:5px;height:5px;border-radius:50%;background:var(--line)}
.model__bd>div.accent{background:var(--accent-soft)}
.model__bd>div.accent ul li::before{background:var(--accent)}
.model__bd>div{display:flex;flex-direction:column}
.model .foot{display:flex;flex-wrap:wrap;gap:5px;margin-top:auto;padding-top:13px}
.model .foot span{font:500 10px/1.5 var(--mono);letter-spacing:.06em;text-transform:uppercase;
  padding:3px 7px;border-radius:5px;border:1px solid var(--line);background:var(--bg);color:var(--muted)}
.model .foot.gate span{color:var(--accent);border-color:color-mix(in srgb,var(--accent) 32%,var(--line));background:var(--accent-soft)}
.model .foot.warn span{color:var(--warn);border-color:color-mix(in srgb,var(--warn) 32%,var(--line));background:var(--warn-soft)}
.model .foot.ok span{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 30%,var(--line));background:var(--ok-soft)}
.model .foot.gate{color:var(--accent)}
.model .foot.ok{color:var(--ok)}
/* Variante: Module als eigene Karten auf einer Fläche */
.model--cards .model__bd{gap:16px;padding:16px;background:var(--bg)}
@media(min-width:700px){.model--cards .model__bd{grid-template-columns:repeat(3,1fr)}}
.model--cards .model__bd>div,
.model--cards .model__bd>div+div{
  border:1px solid var(--line);border-radius:10px;background:var(--raised);
  padding:15px 16px;box-shadow:var(--lift)}
.model--cards .model__hd{border-bottom:0;padding-bottom:4px}
.model--cards>.note{border-top:1px solid var(--line)}

.model>.note{padding:13px 18px;border-top:1px solid var(--line);font-size:12.5px;line-height:1.5;color:var(--muted);background:var(--bg)}

/* decision object mock */
.dobj{border:1px solid var(--line);border-radius:12px;background:var(--raised);overflow:hidden;font-size:13.5px;box-shadow:var(--lift)}
.dobj__hd{padding:12px 16px;border-bottom:1px solid var(--line);display:flex;gap:10px;align-items:center;justify-content:space-between;flex-wrap:wrap}
.dobj__ttl{font-weight:600;font-size:17px;line-height:1.35;letter-spacing:-.016em}
.dobj__bd{padding:15px 16px}
.dobj__row{display:flex;justify-content:space-between;gap:12px;padding:7px 0;border-bottom:1px dashed var(--line)}
.dobj__row:last-of-type{border-bottom:0}
.dobj__row span:first-child{color:var(--muted)}
.dobj__row span:last-child{font-family:var(--mono);font-size:11px}
.dobj__why{margin:13px 0 0;padding:12px 14px;border-radius:9px;background:var(--accent-soft);
  border:1px solid color-mix(in srgb,var(--accent) 24%,var(--line))}
.dobj__why h4{margin-bottom:6px;font-size:12.5px;letter-spacing:.02em}
.dobj__why p{margin:0;font-size:12.5px;line-height:1.5;color:var(--muted)}
.dobj__act{display:flex;gap:9px;flex-wrap:wrap;padding:13px 16px;border-top:1px solid var(--line);background:var(--bg);align-items:center}
.btn{font:500 12.5px/1 var(--sans);letter-spacing:-.005em;padding:9px 14px;border-radius:7px;border:1px solid var(--line);background:var(--raised);color:var(--ink)}
.btn.pri{background:var(--accent);border-color:var(--accent);color:#fff}
html[data-theme="dark"] .btn.pri{color:#0b111b}
.dobj__act .xs{margin-left:auto}

/* confidence bands
   Left stack: Abschnitt, four discrete ticks, Confidence. Fill is data-n,
   not an inline width, so the plate stays token-only. */
.bands{border:1px solid var(--line);border-radius:12px;background:var(--raised);overflow:hidden;margin:6px 0 0;padding:0;box-shadow:var(--lift)}
.bands>li{list-style:none;display:grid;gap:4px 22px;padding:20px 22px;
  grid-template-columns:108px minmax(0,1fr);align-items:start}
.bands>li+li{border-top:1px solid var(--line)}
.bands .lvl{display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding-top:3px}
.bands .ticks{display:flex;gap:3px;width:52px}
.bands .ticks i{flex:1;height:3px;border-radius:1px;background:var(--line)}
.bands .ticks[data-n="1"] i:nth-child(-n+1),
.bands .ticks[data-n="2"] i:nth-child(-n+2),
.bands .ticks[data-n="3"] i:nth-child(-n+3),
.bands .ticks[data-n="4"] i:nth-child(-n+4){background:var(--accent)}
.bands .lab{font:500 10px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);white-space:nowrap}
.bands h4{margin:0 0 4px}
.bands p{margin:0;font-size:14px;line-height:1.5;color:var(--muted)}
.bands .where{grid-column:2;display:flex;flex-wrap:wrap;gap:5px;margin-top:11px}
.bands .where .tag{font-size:9.5px;padding:2px 6px}
@media(max-width:620px){
  .bands>li{grid-template-columns:1fr;gap:9px}
  .bands .where{grid-column:1;margin-top:2px}
}

/* ledger */
.ledger{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:12px;background:var(--raised);overflow:hidden;box-shadow:var(--lift)}
.ledger>div{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:18px 22px}
.ledger>div+div{border-top:1px solid var(--line)}
.ledger h3{margin:0}
.ledger p{margin:4px 0 0;font-size:14px;line-height:1.5;color:var(--muted)}

/* transfer */
.xfer{display:flex;flex-direction:column;gap:16px}
.xfer .card{position:relative;padding:18px 22px 19px}
.xfer .num{font:500 10.5px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent);display:block;margin-bottom:9px}
.xfer h3{margin-bottom:6px}
.xfer p{margin:0;font-size:14px;line-height:1.5;color:var(--muted)}

.callout{border:1px solid color-mix(in srgb,var(--accent) 26%,var(--line));background:var(--accent-soft);
  border-radius:11px;padding:20px 22px;margin:22px 0;box-shadow:var(--lift)}
.callout p{margin:0;font-size:14px;line-height:1.5}
.callout .eyebrow{margin-bottom:6px}

/* ── Bento: Rolle & Handwerk ── */
.bento{display:grid;gap:20px;margin:8px 0 0}
@media(min-width:680px){.bento{grid-template-columns:repeat(2,1fr)}}
.bento>div{border:1px solid var(--line);border-radius:12px;background:var(--raised);
  padding:20px 22px;box-shadow:var(--lift);display:flex;flex-direction:column;min-width:0}
.bento .obj{font:500 10px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent);margin:0 0 9px}
.bento h3{margin:0 0 7px}
.bento p{margin:0;font-size:14px;line-height:1.5;color:var(--muted)}
.bento>div.accent{border-color:color-mix(in srgb,var(--accent) 26%,var(--line));background:var(--accent-soft)}
.bento>div.accent .ev{opacity:.75}
.bento .ev{margin-top:auto;padding-top:13px;font:400 10.5px/1.5 var(--mono);color:var(--muted);opacity:.9}

/* ── Footer als Kontrast-Ende ──
   Always-dark close. Locally remaps ink/muted/line/warn/accent so the
   existing footer pieces keep their token names on the inverted ground. */
footer.site{
  background:var(--end);color:var(--end-ink);border-top:0;margin-top:0;
  --ink:var(--end-ink);--muted:var(--end-muted);--line:var(--end-line);
  --bg:var(--end);--raised:var(--end-raised);
  --warn:var(--end-warn);--warn-soft:var(--end-warn-soft);
  --accent:var(--end-accent);--accent-soft:var(--end-accent-soft)}
#next.band{border-bottom:0}
.site__in{max-width:1180px;margin:0 auto;padding:48px 32px 40px}
.ft-top{display:flex;flex-wrap:wrap;gap:12px 28px;align-items:flex-start;
  justify-content:space-between;margin-bottom:28px}
.ft-id strong{display:block;font-size:17px;letter-spacing:-.016em;font-weight:600;margin-bottom:4px}
.ft-id span{font-size:13.5px;line-height:1.4;color:var(--muted)}
.ft-pre{appearance:none;border:0;background:transparent;padding:4px 0 0;margin:0;
  cursor:pointer;font:500 11px/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted)}
.ft-pre:hover{color:var(--ink)}
.ft-pre:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
.ft-mid{display:grid;gap:28px}
@media(min-width:840px){
  .ft-mid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:32px 56px;align-items:start}
}
.ft-conf{border:1px solid var(--end-conf-line);background:var(--warn-soft);
  border-radius:10px;padding:18px 20px;margin:0}
.ft-conf .eyebrow{color:var(--warn);margin-bottom:8px}
.ft-conf p{margin:0;color:var(--ink);opacity:.88;font-size:12.5px;line-height:1.6}
.ft-defs{display:grid;gap:16px;margin:0;align-content:start}
.ft-def{display:grid;grid-template-columns:1fr;gap:4px;align-items:start;margin:0}
@media(min-width:640px){
  .ft-def{grid-template-columns:104px minmax(0,1fr);gap:6px 20px}
}
.ft-def dt{font:500 10px/1.5 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);margin:0;padding-top:2px}
.ft-def dd{margin:0;font-size:12.5px;line-height:1.55;color:var(--muted)}
.ft-bot{display:flex;flex-wrap:wrap;gap:10px 24px;align-items:center;
  justify-content:space-between;margin-top:32px}
.ft-stand{margin:0;font-size:12.5px;line-height:1.5;color:var(--muted)}
.ft-konami{appearance:none;border:0;background:transparent;padding:0;margin:0;cursor:pointer;
  font:400 12.5px/1.5 var(--mono);letter-spacing:.1em;color:var(--muted)}
.ft-konami:hover{color:var(--ink)}
.ft-konami:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

.kbd{position:fixed;z-index:45;left:50%;bottom:calc(16px + env(safe-area-inset-bottom,0px));
  display:flex;align-items:center;justify-content:center;gap:10px 14px;
  max-width:calc(100% - 24px);padding:8px 14px;border-radius:18px;
  border:1px solid var(--line);isolation:isolate;white-space:nowrap;
  font:400 11px/1.4 var(--mono);color:var(--muted);pointer-events:none;
  transform:translate3d(-50%,var(--kbd-y,0px),0);
  will-change:transform;transition:opacity .22s cubic-bezier(.4,0,.2,1),visibility .22s ease}
.kbd::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  background:var(--glass-fill);box-shadow:var(--lift);
  -webkit-backdrop-filter:var(--glass-filter);backdrop-filter:var(--glass-filter)}
.kbd > span{display:flex;align-items:center;gap:5px}
.kbd__rule{width:1px;height:14px;background:var(--line);flex:none;align-self:center}
.kbd kbd{display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;padding:0;border:1px solid var(--term-line);border-radius:6px;
  background:var(--raised);color:var(--ink);font:500 11px/1 var(--mono)}
.kbd__go{appearance:none;pointer-events:auto;display:inline-flex;align-items:center;gap:5px;
  margin:0;padding:0;border:0;background:transparent;color:inherit;
  font:inherit;letter-spacing:inherit;cursor:pointer;white-space:nowrap}
.kbd__go:hover{color:var(--ink)}
.kbd__go:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
html:has(#lb:not([hidden])) .kbd,
html:has(#ch:not([hidden])) .kbd,
html:has(#toc:not([hidden])) .kbd,
html:not([data-unlocked]) .kbd{opacity:0;visibility:hidden}
@media(max-width:520px){
  .kbd{white-space:normal;flex-wrap:wrap;gap:6px 12px;padding:7px 10px;border-radius:14px}
}
@media(prefers-reduced-motion:reduce){
  .kbd{will-change:auto;transform:translate3d(-50%,0,0);transition:none}
}
/* ── glass ──
   Same plate as .top::before: fill and filter never sit on a sticky element,
   or backdrop-filter goes inert. isolation + z-index:-1 keeps the plate
   behind the content. Used on surfT. */
.glass{isolation:isolate}
.model.glass{position:relative}
.glass::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  background:var(--glass-fill);
  -webkit-backdrop-filter:var(--glass-filter);backdrop-filter:var(--glass-filter)}
/* Head and body of a card module paint --bg, which would hide the frost.
   Clear them for this one instance; the three inner cards keep --raised. */
.model--cards.glass .model__hd,
.model--cards.glass .model__bd{background:transparent}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .top::before,.glass::before,.kbd::before{background:var(--bg)}
}
@media(prefers-reduced-transparency:reduce){
  .top::before,.glass::before,.kbd::before{background:var(--bg);backdrop-filter:none;-webkit-backdrop-filter:none}
}

/* In print the rail and the bands' surfaces carry nothing, so drop the chrome
   and let the shell fall back to its centred, unshifted state. */
@media print{
  html:not([data-unlocked]) body{display:none}
  .top,.rail,.kbd,.lb,.ch,.toc,#gate{display:none}
  .shell{margin-inline:auto;max-width:none}
  .glass::before{background:none;backdrop-filter:none}
  figure:has(>img.zoomable)::before,figure:has(>img.zoomable)::after{display:none}
}

/* Screen-reader-only label, used by the lightbox close control so the
   visible chrome stays an icon while copy still flows through data-i. */
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Medium lightbox: centred panel, not fullscreen. Overlay dim is --overlay
   from tokens.css. Panel reuses the card chrome (--raised, --line, --lift). */
.lb{position:fixed;inset:0;z-index:80;display:flex;align-items:center;justify-content:center;
  padding:24px}
.lb[hidden]{display:none!important}
.lb__backdrop{position:absolute;inset:0;background:var(--overlay);cursor:pointer}
.lb__panel{position:relative;z-index:1;display:flex;flex-direction:column;gap:12px;
  width:min(1100px,78vw);max-height:80vh;padding:16px 16px 14px;
  background:var(--raised);border:1px solid var(--line);border-radius:12px;box-shadow:var(--lift)}
.lb__img{width:100%;max-height:calc(80vh - 88px);height:auto;object-fit:contain;
  border:1px solid var(--line);border-radius:11px;background:var(--bg);box-shadow:none}
.lb__cap{margin:0;font-size:12.5px;line-height:1.52;color:var(--muted)}
.lb__cap:empty{display:none}
.lb__close{position:absolute;top:10px;right:10px;z-index:2;appearance:none;
  width:32px;height:32px;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:7px;background:var(--raised);color:var(--ink);
  cursor:pointer;box-shadow:var(--lift)}
.lb__close:hover{color:var(--ink);background:var(--accent-soft)}
.lb__close:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lb__close svg{display:block;width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}

/* Konami pre-read reuses the lightbox overlay (--overlay, close chrome) with
   a tighter panel and the lavender-gray cells from the fit bento. */
.ch .ch__panel{position:relative;z-index:1;display:flex;flex-direction:column;gap:16px;
  width:min(840px,92vw);max-height:88vh;overflow:auto;padding:22px 24px 16px;
  background:var(--raised);border:1px solid var(--line);border-radius:12px;box-shadow:var(--lift)}
.ch__seq{margin:0;font:400 11px/1.4 var(--mono);letter-spacing:.1em;color:var(--muted)}
.ch__title{max-width:none;text-wrap:balance;font-size:25px;line-height:1.1;letter-spacing:-.03em;margin:0 36px 2px 0}
.ch__grid{display:grid;gap:10px}
@media(min-width:640px){.ch__grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
.ch__grid>div{border:1px solid color-mix(in srgb,var(--accent) 16%,var(--line));
  background:color-mix(in srgb,var(--accent) 7%,var(--bg));
  border-radius:10px;padding:14px 16px}
.ch__grid .obj{font:500 10px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent);margin:0 0 8px}
.ch__grid p{margin:0;font-size:14px;line-height:1.5;color:var(--ink)}
.ch__foot{margin:4px 0 0;font-size:12.5px;line-height:1.5;color:var(--muted)}
.ch .lb__close{top:16px;right:16px}

/* Chapter navigator: same overlay family as #lb / #ch, hairlines not cards.
   Rows stay dense so ten chapters fit as a list, not a stack of blocks. */
.toc .toc__panel{position:relative;z-index:1;display:flex;flex-direction:column;
  width:min(520px,92vw);max-height:88vh;overflow:auto;padding:16px 20px 6px;
  background:var(--raised);border:1px solid var(--line);border-radius:12px;box-shadow:var(--lift)}
.toc__title{max-width:none;font-size:22px;line-height:1.1;letter-spacing:-.03em;
  font-weight:620;margin:0 36px 10px 0}
.toc__list{display:flex;flex-direction:column;margin:0 -20px;padding:0;
  border-top:1px solid var(--line)}
.toc__row{appearance:none;display:grid;grid-template-columns:1.9em minmax(0,1fr) auto;
  gap:1px 10px;align-items:start;width:100%;margin:0;padding:7px 20px;
  border:0;border-bottom:1px solid var(--line);background:transparent;
  color:inherit;text-align:left;cursor:pointer;font:inherit}
.toc__row:hover{background:var(--accent-soft)}
.toc__row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.toc__row[aria-current="true"]{box-shadow:inset 2px 0 0 var(--accent)}
.toc__n{font:500 10.5px/1.3 var(--mono);letter-spacing:.04em;color:var(--muted);padding-top:2px}
.toc__row[aria-current="true"] .toc__n{color:var(--accent)}
.toc__tx{display:flex;flex-direction:column;gap:1px;min-width:0}
.toc__h{font-size:13.5px;line-height:1.22;letter-spacing:-.01em;font-weight:600;color:var(--ink)}
.toc__b{font-size:12.5px;line-height:1.32;color:var(--muted)}
.toc__t{font:400 10.5px/1.3 var(--mono);letter-spacing:0;color:var(--muted);padding-top:2px;white-space:nowrap}
.toc .lb__close{top:12px;right:12px}
@media(max-width:640px){
  .toc{align-items:flex-end;padding:0}
  .toc .toc__panel{width:100%;max-height:92vh;border-radius:16px 16px 0 0;
    padding:14px 16px calc(8px + env(safe-area-inset-bottom,0px))}
  .toc__list{margin:0 -16px}
  .toc__row{padding:7px 16px}
}

/* ── password gate ──
   The case lives in #stage and is strongly blurred while gated. #gate is a
   thin veil plus the panel — not an opaque sheet. Unlock is a JS flag;
   CSS display:none on #gate is forced back until that flag is set.
   Opening fades veil and blur together. */
#stage{transition:filter .7s ease,transform .7s ease}
html:not([data-unlocked]) #stage{
  filter:blur(44px) saturate(140%);transform:scale(1.045);
  pointer-events:none;user-select:none}
#gate{position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;
  background:var(--gate-veil);padding:24px;
  transition:opacity .55s ease}
html[data-unlocked] #gate{opacity:0}
html:not([data-unlocked]){overflow:hidden}
.gate__panel{width:min(440px,100%);padding:32px 32px 28px;border:1px solid var(--line);
  border-radius:12px;background:var(--raised);box-shadow:var(--lift);
  display:flex;flex-direction:column;gap:12px}
.gate__top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  padding-bottom:16px;margin-bottom:4px;border-bottom:1px solid var(--line)}
.gate__panel .brand{font-size:16px;line-height:1.2;margin:0;padding-top:4px}
.gate__panel h2{margin:0;max-width:none;font-size:25px;line-height:1.1;letter-spacing:-.03em;font-weight:620}
.gate__panel .lead{margin:0;font-size:15px;line-height:1.48;color:var(--muted)}
.gate__panel .eyebrow{margin:0}
.gate__row{display:flex;gap:8px;align-items:stretch;margin-top:6px}
.gate__row input{flex:1;min-width:0;appearance:none;font:400 15px/1.4 var(--sans);
  letter-spacing:-.006em;padding:12px 14px;border:1px solid var(--line);border-radius:7px;
  background:var(--bg);color:var(--ink)}
.gate__row input:focus{outline:2px solid var(--accent);outline-offset:1px}
.gate__row .btn{flex:none;padding:12px 18px}
.gate__err{margin:0;font-size:12.5px;line-height:1.5;color:var(--danger)}
.gate__err[hidden]{display:none}
@media(prefers-reduced-motion:reduce){
  #stage,#gate{transition:none}
}
