
@font-face{font-family:"IBM Plex Sans";src:url("fonts/IBMPlexSans-Light.woff2") format("woff2");font-style:normal;font-weight:300;font-display:swap}
@font-face{font-family:"IBM Plex Sans";src:url("fonts/IBMPlexSans-Regular.woff2") format("woff2");font-style:normal;font-weight:400;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url("fonts/IBMPlexMono-Regular.woff2") format("woff2");font-style:normal;font-weight:400;font-display:swap}
/* ONE stylesheet, one block per selector (v9 A1); media variants last, in cascade order */
:root{
  --cream:#EDE6D6; --cream-2:#E5DECF; --cream-rgb:237,230,214;
  --ink:#2E3134; --rust:#9C4A24; --slate:#7A7C7F; --fjord:#33566E;
  /* v9 R: the approved identity's STOREN SCREEN RED (2026-10-08) — the
     wordmark and the mark on paper; white on the graphite night */
  --red:#ee3124;
  --i70:rgba(46,49,52,.82); --i45:rgba(46,49,52,.72); --i28:rgba(46,49,52,.55); --i14:rgba(46,49,52,.18);
  --tech:"IBM Plex Mono",ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sans:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --sp:clamp(20px,3.6vw,52px);
  /* motion by role: hover, ui panels, drawer/card move, globe cross-fade */
  --t-hover:.25s; --t-ui:.32s; --t-move:.62s; --t-space:1.1s;
  --ease-out:cubic-bezier(.16,1,.3,1);
  /* spacing ladder (F028) for the card/drawer/panel family */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px;
  /* line-heights for genuine multi-line prose */
  --lh-body:1.65; --lh-prose:1.75;
  /* drawer width and scrim offset, one source */
  --drawer-w:min(480px,100vw);
  /* ---- v9 system tokens: defined now, applied by B1/C ---- */
  /* motion: durations by role, easings, springs (springs below) */
  --dur-press:110ms; --dur-hover-in:160ms; --dur-hover-out:240ms; --dur-micro:180ms;
  --dur-pop:220ms; --dur-card:300ms; --dur-exit:180ms; --dur-morph:470ms;
  --dur-sheet:500ms; --dur-scene:1100ms; --stagger:40ms;
  --ease-ui:cubic-bezier(.23,1,.32,1); --ease-expo:cubic-bezier(.16,1,.3,1);
  --ease-in-out:cubic-bezier(.77,0,.175,1); --ease-standard:cubic-bezier(.2,0,0,1);
  --ease-sheet:cubic-bezier(.32,.72,0,1);
  /* spring fallbacks: cubic fits of the linear() shapes below (err ≤.027) */
  --spring-smooth:cubic-bezier(.28,.41,.07,1); --spring-snappy:cubic-bezier(.37,.59,.06,1);
  --spring-sheet:cubic-bezier(.26,.22,.17,1); --spring-bouncy:cubic-bezier(.28,.35,.08,1.24);
  /* radii: glass card, phone sheet, paper mount, thumbnails, buttons, capsules */
  --r-card:20px; --r-sheet:24px; --r-inner:12px; --r-thumb:6px; --r-btn:10px; --r-cap:999px;
  /* one sun (NW): every shadow falls SE at x:y = 1:2, warm ink, layered */
  --sh-1:1px 2px 2px rgba(46,40,30,.07),2px 4px 8px rgba(46,40,30,.06);
  --sh-2:1px 2px 2px rgba(46,40,30,.06),3px 6px 12px rgba(46,40,30,.07),6px 12px 24px rgba(46,40,30,.06);
  --sh-3:1px 2px 2px rgba(46,40,30,.05),4px 8px 16px rgba(46,40,30,.06),8px 16px 32px rgba(46,40,30,.07),16px 32px 64px rgba(46,40,30,.07);
  /* stacking, back to front */
  --z-space:0; --z-limb:4; --z-tint:5; --z-sky:6; --z-birds:7; --z-warp:8; --z-card:16;
  --z-chrome:20; --z-close:24; --z-panel:26; --z-menu:31; --z-menu-btn:32;
  --z-drawer:34; --z-scrim:35; --z-shot:39; --z-page:40; --z-page-x:41; --z-lb:60; --z-ns:99;
  /* type scale */
  --fs-caption2:11px; --fs-caption:12px; --fs-footnote:13px; --fs-sub:15px; --fs-body:17px;
  --fs-title3:22px; --fs-title2:30px; --fs-title1:44px; --fs-display:56px;
  /* ---- v9 B1 glass over paper: content on --paper (a step lighter than the
     atlas), the functional layer frosted glass ≤1 OKLab b cooler than the
     cream. Sheets and capsules are two weights of one recipe; space and every
     fallback are variable swaps */
  --paper:#F6F2E8; --grain:url(img/fx/grain.png) 0 0/128px 128px;
  --g-tint:rgba(246,242,232,.74); --g-tint-c:rgba(246,242,232,.6); --g-grain:var(--grain);
  --g-frost:blur(22px) saturate(1.7) brightness(1.06) contrast(.9);
  --g-frost-c:blur(14px) saturate(1.7) brightness(1.06) contrast(.9);
  /* the specular rim: one sun (NW) wins at any aspect, a faint glint SE */
  --g-rim:linear-gradient(to bottom right,#fff,rgba(255,255,255,.2) 30%,rgba(255,255,255,.05) 60%,rgba(255,255,255,.28));
  --g-hair:0 0 0 .5px rgba(46,40,30,.2);
  /* lens-lite: the capsule's thick edge catches light NW and dims SE */
  --g-band:inset 1.5px 2px 3px -1px rgba(255,255,255,.7),inset -1.5px -2px 4px -2px rgba(46,40,30,.12);
  --plate:rgba(246,242,232,.72); --hov:rgba(46,49,52,.06); --sel:rgba(46,49,52,.085); --g-on:rgba(252,250,245,.9); --g-glow:rgba(255,255,255,.42);
  --sheet:rgba(246,242,232,.84);
  /* named properties only: never all, never opacity (surfaces fade by
     app.js's UI MOTION region); one press token (C3) */
  --tr-btn:color var(--dur-hover-out) var(--ease-ui),background-color var(--dur-hover-out) var(--ease-ui),border-color var(--dur-hover-out) var(--ease-ui),transform var(--dur-press) var(--ease-ui);
}
/* the night: smoked glass (cooled for the black-blue space), dimmer rim, the dark grain */
/* (a lit globe must not lift a sheet to mid-grey; About/Terms stay paper).
   B3 marks each piece of chrome .on-night while the pixels behind it are
   night; body.space = all of it is. One material for both */
body.space,.on-night{--g-tint:rgba(28,32,44,.88); --g-tint-c:rgba(28,32,44,.68); --g-grain:url(img/fx/grain-space.png) 0 0/128px 128px;
  --g-rim:linear-gradient(to bottom right,rgba(255,255,255,.4),rgba(255,255,255,.07) 30%,rgba(255,255,255,.02) 60%,rgba(255,255,255,.12));
  --g-hair:0 0 0 .5px rgba(0,0,0,.5); --plate:rgba(20,24,36,.62); --g-on:rgba(56,62,78,.88); --g-glow:rgba(255,255,255,.1); --sheet:var(--paper);
  --g-band:inset 1.5px 2px 3px -1px rgba(255,255,255,.14),inset -1.5px -2px 4px -2px rgba(0,0,0,.3)}
/* chrome that sits on smoked glass in space reads in cream */
body.space :is(#menuBtn,#mapNav,#hint,#menu,#readout,.maplibregl-ctrl-bottom-right),:is(#menuBtn,#mapNav,#hint,#readout).on-night{--ink:var(--cream);
  --i70:rgba(237,230,214,.84); --i45:rgba(237,230,214,.74); --i28:rgba(237,230,214,.5); --i14:rgba(237,230,214,.18);
  --hov:rgba(237,230,214,.1); --sel:rgba(237,230,214,.15); color:var(--ink)}
@supports (transition-timing-function:linear(0,1)){:root{
  /* ζ=1, bounce 0 (470ms) */
  --spring-smooth:linear(0,.005 1.2%,.02 2.5%,.046 4%,.08 5.5%,.163 8.5%,.363 15%,.458 18.2%,.55 21.8%,.63 25.2%,.695 28.5%,.753 32%,.805 35.8%,.847 39.5%,.886 44%,.919 49%,.945 54.5%,.964 60.8%,.978 67.5%,.988 75.5%,1);
  /* bounce .12 (490ms), peak 1.002 */
  --spring-snappy:linear(0,.006 1.5%,.024 3%,.055 4.8%,.094 6.5%,.184 9.8%,.397 16.8%,.499 20.2%,.591 23.8%,.672 27.3%,.737 30.5%,.796 34%,.844 37.5%,.883 41%,.92 45.2%,.95 50%,.972 55.2%,.987 61%,.997 67.5%,1.002 75.8%,1);
  /* bounce .08 (500ms) — drawer/sheet */
  --spring-sheet:linear(0,.006 1.8%,.021 3.5%,.049 5.5%,.089 7.8%,.176 11.8%,.382 20.2%,.469 24%,.555 28%,.631 32%,.69 35.5%,.741 39%,.786 42.5%,.827 46.2%,.869 51%,.904 56%,.933 61.5%,.955 67.2%,.972 73.5%,.984 80.5%,1);
  /* bounce .25 (620ms), peak 1.027 — marker drop / add-to-bag only */
  --spring-bouncy:linear(0,.006 1.5%,.024 3%,.056 4.8%,.104 6.8%,.209 10.2%,.452 17.5%,.556 20.8%,.651 24%,.734 27.3%,.799 30.2%,.859 33.5%,.908 36.8%,.948 40.2%,.98 44%,1.003 48%,1.019 52.5%,1.027 57.5%,1.027 66.5%,1);
}}
*{box-sizing:border-box;margin:0;padding:0}
/* the root never scrolls: no pull-to-refresh under an open checkout */
html{overscroll-behavior:none}
html,body{height:100%}
body{background:var(--cream);color:var(--ink);font:400 15px/1.6 var(--sans);overflow:hidden;-webkit-font-smoothing:antialiased;
  font-synthesis:none}
/* only Plex 300/400 ship: emphasis is full ink, never a smeared faux bold */
strong,b{font-weight:400;color:var(--ink)}
noscript .ns{position:fixed;inset:0;z-index:var(--z-ns);background:var(--cream);display:flex;align-items:center;justify-content:center;text-align:center;padding:32px}
noscript .ns div{max-width:44ch}
/* was an inline style attribute — blocked once style-src drops 'unsafe-inline' */
.nsImg{width:min(300px,70vw)}
/* until the world loads the instruments stay off an empty stage */
body:not(.ready) #mark,body:not(.ready) #creed,body:not(.ready) #menuBtn,
body:not(.ready) #readout,body:not(.ready) #hint{opacity:0}
body:not(.ready) .maplibregl-marker{visibility:hidden}
/* the first visibility pass lands without a fade: a mark the gathering hides
   must never ghost out over it in the opening frames (review r1) */
body:not(.mklive) .maplibregl-marker{transition:none!important}
body:not(.ready) #creed,body:not(.ready) #mapNav{visibility:hidden}
/* manipulation: no double-tap zoom throwing the fixed chrome off its corners */
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;touch-action:manipulation}
button,a,input,summary{-webkit-tap-highlight-color:transparent}
/* one focus ring, two-tone (2px core + 4px halo of the opposite tone),
   following the control's radius — reads on cream, glass and graphite */
:focus-visible{outline:2px solid var(--ink);outline-offset:2px;box-shadow:0 0 0 6px rgba(250,248,242,.92)}
.maplibregl-ctrl-attrib-button:focus{box-shadow:none}
/* cream ring only on graphite chrome; paper in space keeps the ink ring */
body.space :is(#menuBtn,#compass,#mapNav *,#menu *,#creed *,.maplibregl-ctrl *):focus-visible,
#menuBtn.on-night:focus-visible,:is(#mapNav,#creed).on-night :focus-visible{outline-color:var(--cream);box-shadow:0 0 0 6px rgba(20,21,23,.86)}
/* text-only controls: a soft corner and some air, never a hard box */
:where(button,a,summary,[tabindex]):focus-visible{border-radius:var(--r-thumb)}
:is(.ghost,#ckBack,.tlink):focus-visible{outline-offset:4px}
/* text that wraps is set, not left to fall */
h2,h3,h4{text-wrap:balance}
p,dd,.figcap{text-wrap:pretty}
/* [hidden] always wins over .buy/.fld display */
[hidden]{display:none!important}
/* visually-hidden text (F050) — read by assistive tech only */
.srOnly{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* v9 hook: never display:none, or url(#…) filters stop resolving */
.fx-defs{position:absolute;width:0;height:0;overflow:hidden;pointer-events:none}

/* ---------- glass (v9 B1) ----------
   host: isolation, radius, SE shadow — never blurred itself. ::before = the
   material (pointer glow, grain, tint, frost), ::after = the specular rim cut
   to a 1px ring. ≤4 frosted at once. Never fade/clip/filter a host or its
   ancestor: that is a backdrop root and the frost drops out until it ends —
   fade ::before/::after/content instead */
#menuBtn,#mapNav,#compass,#card,#cardClose,#drawer,#menu,#hint{isolation:isolate;border:0;background:none}
:is(#menuBtn,#mapNav,#compass,#card,#cardClose,#drawer,#menu,#hint)::before,
:is(#menuBtn,#mapNav,#compass,#card,#cardClose,#drawer,#menu,#hint)::after{content:"";position:absolute;inset:0;
  border-radius:inherit;pointer-events:none}
:is(#menuBtn,#mapNav,#compass,#card,#cardClose,#drawer,#menu,#hint)::before{z-index:-1;
  /* the pointer light (B3 writes --px/--py) shows only under a hovering pointer */
  background:radial-gradient(56px circle at var(--px,50%) var(--py,50%),var(--glow,#fff0),#fff0),var(--g-grain),var(--g-tint-c);
  -webkit-backdrop-filter:var(--g-frost-c);backdrop-filter:var(--g-frost-c);box-shadow:var(--g-band),var(--g-hair),var(--sh-1);
  transition:background-color var(--dur-hover-out) var(--ease-ui),opacity var(--t-ui) var(--ease-ui)}
#card::before,#drawer::before,#menu::before{background:var(--g-grain),var(--g-tint);
  -webkit-backdrop-filter:var(--g-frost);backdrop-filter:var(--g-frost);box-shadow:var(--g-hair),var(--sh-3)}
/* hosts that may clip (card, menu) or split (zoom) carry the shadow */
#card::before,#menu::before{box-shadow:none}
#mapNav::before{box-shadow:var(--g-band)}
:is(#menuBtn,#mapNav,#compass,#card,#cardClose,#drawer,#menu,#hint)::after{padding:1px;background:var(--g-rim);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;
  transition:opacity var(--t-ui) var(--ease-ui)}
/* C3: these fade by the UI MOTION region (app.js) — one owner */
#card::before,#card::after,#menu::before,#menu::after,#drawer::before,#drawer::after{transition:none}
/* Chromium only, never needed for the look (B3: html.fx-refract + --fx-lens
   per capsule once live). A lens of another size clips the backdrop: only
   the round 44px compass may fall back to fx-lens-44 */
html.fx-refract :is(#menuBtn,#mapNav,#cardClose)::before{
  backdrop-filter:blur(.75px) var(--fx-lens,) saturate(1.1) brightness(1.04)}
html.fx-refract #compass::before{backdrop-filter:blur(.75px) var(--fx-lens,url(#fx-lens-44)) saturate(1.1) brightness(1.04)}
/* over the lit 3D city the capsules take the top of their band: building
   shadows read as grey blotches through a thinner frost (review r1) */
body.orbit{--g-tint-c:rgba(246,242,232,.62);--g-frost-c:blur(16px) saturate(1.7) brightness(1.06) contrast(.9)}
/* one sheet at a time: while the drawer or the menu is up, the card behind
   is paper, not a second pane of glass (class swap, never a blur tween) */
body:has(#drawer.on,#drawer.leave,#menu.on,#menu.leave) #card::before{-webkit-backdrop-filter:none;backdrop-filter:none;background-color:var(--paper);transition:none}
/* the press: everything you can push gives a little */
:is(#menuBtn,#mapNav .icon,#compass,#cardClose,#exploreNorway,.buy,.sizes button,.dSizes button,.vBtn,.strip button,.wlRow button,#pinVote,#pinCancel,
  #menu button,.galnav button,.ghost,#ckBack,#drawerClose,#aboutX,#legalX,#lbX,#histX,#pinX,#histPanel .hnav button,#pinPanel .pa button):active:not([disabled]){transform:scale(.97)}
.lbArrow:active{transform:translateY(-50%) scale(.97)}

/* ---------- space ---------- (shows through the transparent canvas) */
/* real space: a deep black-blue night #0E1220 → #05070D in OKLab + grain
   (kills banding); the sky itself is app.js's canvases (v9 S) */
#space{position:fixed;inset:0;z-index:var(--z-space);pointer-events:none;opacity:0;overflow:hidden;background:#090C15;
  background:url(img/fx/grain-space.png) 0 0/128px 128px,radial-gradient(farthest-corner at 50% 46% in oklab,rgb(14 18 32),rgb(5 7 13))}
/* the wrapper carries opacity and the cinematic scale for all three layers;
   each layer is sized by app.js with a 40 px bleed (the drag parallax) */
#stars{position:absolute;inset:0}
.sl{position:absolute;left:-40px;top:-40px;display:block}
/* no CSS twinkle: stars move only under input (B3); 0-fps rest */
#map{position:fixed;inset:0}
/* the limb, lit from the NW: SE terminator inside the disc, rim light
   outside it. B3 writes --limb-x/-y/-r (px lengths) and --limb-o (0–1) */
#limb{position:fixed;inset:0;z-index:var(--z-limb);pointer-events:none}
#limb::before,#limb::after{content:"";position:absolute;inset:0;opacity:var(--limb-o,0)}
#limb::before{background:radial-gradient(circle at calc(var(--limb-x) - var(--limb-r) * .5) calc(var(--limb-y) - var(--limb-r) * .5),
    transparent calc(var(--limb-r) * 1.02),rgba(14,18,32,.46) calc(var(--limb-r) * 1.62));
  mask:radial-gradient(circle at var(--limb-x) var(--limb-y),#000 calc(var(--limb-r) - .5px),transparent calc(var(--limb-r) + .5px))}
/* the atmosphere: a thin blue-white shell hugging the limb (a haze just
   inside, the bright line, a short falloff out), brightest NW, a faint
   thread all the way round */
#limb::after{background:radial-gradient(circle at var(--limb-x) var(--limb-y),transparent calc(var(--limb-r) - 8px),
    rgba(150,190,255,.14) calc(var(--limb-r) - 2.5px),rgba(232,242,255,.8) var(--limb-r),rgba(156,196,255,.34) calc(var(--limb-r) + 2px),
    rgba(100,150,240,.12) calc(var(--limb-r) * 1.01 + 6px),transparent calc(var(--limb-r) * 1.025 + 14px));
  mask:radial-gradient(circle at calc(var(--limb-x) - var(--limb-r) * .7) calc(var(--limb-y) - var(--limb-r) * .7),#000 calc(var(--limb-r) * .35),rgba(0,0,0,.16) calc(var(--limb-r) * 1.65))}
/* NO transition: the gsap reveal starts from zero behind the warp veil */
body.galaxy #map{opacity:0}
body.space #mark,#mark.on-night{color:#fff;--mk-halo:rgba(10,13,24,.55)}
body.space #creed,#creed.on-night{color:rgba(var(--cream-rgb),.78)}
/* without top/left every mark lands a multiple of 22px low */
.maplibregl-marker{position:absolute;top:0;left:0;margin:0}
/* instruments = tint plates: no frost, Plex Mono, tabular; attribution clears AA */
.maplibregl-ctrl-attrib{background-color:var(--plate)!important}
.maplibregl-ctrl-bottom-right .maplibregl-ctrl-attrib{font:400 11px/1.45 var(--tech);color:var(--i70)}
.maplibregl-ctrl-attrib a{color:var(--i70)}
/* (i): a plate with an ink "i", never the stock black disc */
.maplibregl-ctrl-attrib-button{background:var(--plate)!important;color:var(--i70)}
.maplibregl-ctrl-attrib-button::before{content:"";position:absolute;inset:0;background:currentColor;
  -webkit-mask:var(--i-glyph);mask:var(--i-glyph);--i-glyph:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M9 7a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E") 50%/24px no-repeat}
/* the card and the drawer hold that corner */
body:has(#drawer.on,#drawer.leave) .maplibregl-ctrl-bottom-right{visibility:hidden}
.maplibregl-canvas{cursor:crosshair}

/* born hidden: syncSky fades it in when land arrives */
#sky{position:fixed;top:0;left:0;right:0;height:32vh;z-index:var(--z-sky);pointer-events:none;will-change:transform;opacity:0}
#sky svg{width:100%;height:100%;display:block}
/* weather is cinematic-only */
body.survey #sky,body.survey #birds{display:none}
.cloud{animation:drift 120s linear infinite}
.cloud.b{animation-duration:170s;animation-direction:reverse}
.cloud.c{animation-duration:230s}
@keyframes drift{from{transform:translateX(-16%)}to{transform:translateX(116%)}}

/* v9 R (owner 2026-10-18): the "Støren" script wordmark of the approved
   2026-10-08 identity — img/identity/storen-wordmark.svg, the master outline
   verbatim, drawn as a mask in currentColor: STOREN SCREEN RED on the paper
   map, white on the graphite night (body.space / .on-night swap the colour
   in one frame, no transition). --wm-h = the ink height H; the box is the
   file's viewBox, ink + 0.40·H clear space on every side, never stretched
   (3.788·H × 1.8·H). Its ink centre sits on the Menu pill's centre line */
#mark{position:fixed;--wm-h:clamp(30px,2.75vw,40px);
  top:calc(clamp(20px,4.5vh,44px) + 22px - var(--wm-h) * .9 + env(safe-area-inset-top,0px));left:50%;z-index:var(--z-chrome);
  width:calc(var(--wm-h) * 3.78826);height:calc(var(--wm-h) * 1.8);margin:0;color:var(--red);
  /* it shrinks by transform, never by size: no layout per frame */
  transform:translateX(-50%) scale(var(--mk-s,1));transform-origin:50% 50%;
  transition:transform var(--dur-morph) var(--ease-ui),opacity var(--dur-card) var(--ease-ui);
  /* a ground-matched halo: map labels passing under the wordmark recede */
  --mk-halo:rgba(var(--cream-rgb),.9);filter:drop-shadow(0 0 1px var(--mk-halo)) drop-shadow(0 0 7px var(--mk-halo))}
#mark::before,#aboutH::before{content:"";position:absolute;inset:0;background:currentColor;
  -webkit-mask:url(img/identity/storen-wordmark.svg) 50% 50%/100% 100% no-repeat;mask:url(img/identity/storen-wordmark.svg) 50% 50%/100% 100% no-repeat}
/* it swallows its own click (review r1: the map under it flew to the North
   Pacific); app.js makes it the home gesture — back to the world */
body.hascard #mark{pointer-events:none}
#mark.small{--mk-s:.58}
#mark.dim{opacity:.5}
/* at a place, the place is the hero — the circular mark keeps the brand on screen */
body.hascard #mark{opacity:0}

#birds{position:fixed;inset:0;z-index:var(--z-birds);pointer-events:none;opacity:0}
#birds path{fill:none;stroke:rgba(46,49,52,.45);stroke-width:1.2;stroke-linecap:round}

/* v9 R (owner 2026-10-18): only at a place (#readout.on, app.js
   showReadout) — its name and its chest coordinates; never on the world,
   Norway or the open map, never a zoom number. The card says it already */
#readout{position:fixed;left:calc(var(--sp) + env(safe-area-inset-left,0px));bottom:calc(var(--sp) + 18px + env(safe-area-inset-bottom,0px));z-index:var(--z-chrome);
  padding:7px 12px 6px;border-radius:var(--r-btn);background:var(--plate);color:var(--ink);
  pointer-events:none;opacity:0;visibility:hidden;transition:opacity .4s,visibility 0s linear .4s}
#readout.on{opacity:1;visibility:visible;transition:opacity .4s}
body.hascard #readout{opacity:0;visibility:hidden}
/* plate and ink swap with the ground in one frame, as #space does (review
   r1: a 1.1 s fade left a muddy grey plate at the opening and on every
   return to the world) */
#ro-name{font:400 13px/1.5 var(--sans);letter-spacing:.01em}
/* the readout is essential information — it must clear WCAG AA on cream, not sit at 3:1 */
#ro-coord{font:400 11px/1.7 var(--tech);letter-spacing:.02em;color:var(--i70);font-variant-numeric:tabular-nums}

/* the creed: above the readout on small screens; fades as you fall */
#creed{position:fixed;left:calc(var(--sp) + env(safe-area-inset-left,0px));top:33%;z-index:var(--z-chrome);width:min(310px,26vw);
  font:300 clamp(17px,1.5vw,22px)/1.55 var(--sans);color:var(--i70);
  transition:opacity var(--t-hover),visibility var(--t-hover)}
#creed h2{font:300 clamp(30px,3.6vw,50px)/1.08 var(--sans);letter-spacing:-.03em;
  color:var(--ink);margin-bottom:20px}
/* the prominent capsule: ink on paper, smoked plate in space (not a frosted host) */
#creed #exploreNorway{display:flex;justify-content:space-between;align-items:center;gap:28px;
  min-height:48px;margin-top:26px;padding:0 16px 0 22px;border:0;border-radius:var(--r-cap);
  font:400 15px/1 var(--sans);letter-spacing:.005em;background:var(--ink);color:var(--cream);
  box-shadow:inset 1px 1px 0 rgba(255,255,255,.14),var(--sh-2);transition:var(--tr-btn)}
#creed #exploreNorway span{font-size:19px}
body.space #creed h2,#creed.on-night h2{color:var(--cream)}
body.space #creed #exploreNorway,#creed.on-night #exploreNorway{background:var(--g-grain),rgba(52,58,74,.74);color:var(--cream);
  box-shadow:inset 1px 1px 0 rgba(255,255,255,.2),inset 0 0 0 .5px rgba(237,230,214,.3),0 2px 6px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.28)}
/* the menu and the pin panel take the creed's column (B4: phones; every width
   since the integration — on a tablet its heading peeked out under the menu) */
/* C3: back only once the menu or pin panel has gone (.leave), never through it */
body.engaged #creed,body.hascard #creed,body:has(#pinPanel.on,#pinPanel.leave,#menu.on,#menu.leave) #creed{visibility:hidden;pointer-events:none;opacity:0!important}
/* C3: it steps out of the way at once (press time) — the menu's glass
   fading in over a half-gone headline read as ghost text under the rows */
body:has(#pinPanel.on,#menu.on) #creed{transition:opacity var(--dur-press) var(--ease-ui),visibility 0s linear var(--dur-press)}

/* ---------- the menu ---------- */
#menuBtn{position:fixed;left:calc(var(--sp) + env(safe-area-inset-left,0px));top:calc(clamp(20px,4.5vh,44px) + env(safe-area-inset-top,0px));
  z-index:var(--z-menu-btn);width:102px;height:44px;display:flex;place-items:center;justify-content:center;gap:10px;
  border-radius:var(--r-cap);transition:var(--tr-btn)}
/* the approved circular mark of 2026-10-08 (.stm, below); red on paper,
   white on the night. 34 px: the floor where the 0.61-of-42 slash reaches
   ~1 device px at dpr 2 (R fix r1, measured) */
#menuBtn .stm{width:34px;height:34px;color:var(--red)}
body.space #menuBtn .stm,#menuBtn.on-night .stm{color:#fff}
/* open: the pill thickens — no ink inversion; the menu grows from it */
#menuBtn.on{--g-tint-c:var(--g-on)}
/* the label is always on, beside the circular mark */
#menuBtn .btnl{position:static;left:calc(100% + 9px);top:50%;transform:none;
  font:400 13px/1 var(--sans);letter-spacing:0;text-transform:none;color:inherit;
  background:none;padding:0;opacity:1;pointer-events:none;white-space:nowrap}
/* the open state keeps the 13px face even where the phone rule shrinks it (B1) */
#menuBtn.on .btnl{font:400 13px/1 var(--sans)}

/* #menu is the non-scrolling host; #menuList inside it is the scroller.
   overflow:clip keeps the list (row tints, the first row's focus ring)
   inside the corners, as the old overflow:auto did — and cannot scroll
   (v9 A fix r1); the host's shadow is box-shadow, so the clip keeps it */
#menu{--mp:14px;position:fixed;left:calc(var(--sp) + env(safe-area-inset-left,0px));top:calc(clamp(20px,4.5vh,44px) + env(safe-area-inset-top,0px) + 56px);
  z-index:var(--z-menu);width:min(324px,86vw);border-radius:var(--r-card);
  visibility:hidden;pointer-events:none;
  /* it fits the viewport under the pill (B4): every place and the footer stay
     reachable on a landscape phone */
  display:flex;flex-direction:column;max-height:calc(100dvh - clamp(20px,4.5vh,44px) - env(safe-area-inset-top,0px) - 72px);overflow:clip}
#menuList{min-height:0;padding:6px;overflow-y:auto;overscroll-behavior:contain}
/* C3: rest states — it grows from the pill by the UI MOTION region (app.js) */
#menu.on,#menu.leave{visibility:visible;box-shadow:var(--g-hair),var(--sh-3)}
#menu.on{pointer-events:auto}
/* more below the fold: the list fades at its foot (on the scroller, never the host) */
#menu.more #menuList{-webkit-mask-image:linear-gradient(#000 calc(100% - 36px),transparent);mask-image:linear-gradient(#000 calc(100% - 36px),transparent)}
/* Terms · Sound · language stay in view under the scroller (B4; L fills
   the slot); v9-M: its end words on the list's text edges */
#menuFoot{flex:none;padding:0 6px 6px}
#menu .mfoot{display:flex;align-items:center;gap:2px;border-top:1px solid var(--i14);margin:0 var(--mp)}
#menu .mf{min-height:44px;min-width:44px;padding:0 10px;border-radius:var(--r-btn);font:400 12px/1 var(--sans);letter-spacing:.01em;
  color:var(--i70);transition:var(--tr-btn)}
#menu .mfoot>.mf:first-child{margin-left:-10px}
/* World | Norway (v9-M): the pressed half a tint inside its 44 px target */
#menu .mview{display:flex;margin:0 0 2px;border-radius:var(--r-cap);box-shadow:inset 0 0 0 1px var(--i14)}
#menu .mv{flex:1;min-height:44px;padding:4px;background-clip:content-box;border-radius:var(--r-cap);
  font:400 13px/1 var(--sans);letter-spacing:.01em;color:var(--i45);transition:var(--tr-btn)}
#menu .mv[aria-pressed="true"]{background-color:var(--sel);color:var(--ink)}
#menu .mplaces,#menu .mrank{list-style:none;margin:0;padding:0}
/* place and square rows: the whole row lifts on hover, 44px targets */
#menu .mp,#menu .mr{display:flex;align-items:center;border-radius:var(--r-btn);
  transition:background-color var(--dur-hover-out) var(--ease-ui)}
#menu .mpGo{flex:1;min-width:0;min-height:44px;display:flex;align-items:center;gap:12px;text-align:left;
  padding:4px var(--mp);border-radius:var(--r-btn);transition:var(--tr-btn)}
#menu .mr .mpGo{flex-direction:column;align-items:flex-start;justify-content:center;gap:0}
/* v9-M glyph: solid = made, ring = drawing */
#menu .mp .gl{flex:none;width:8px;height:8px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--i70)}
#menu .mp.made .gl{background:currentColor;box-shadow:none}
#menu .mpGo .fn{font:300 16px/1.25 var(--sans);letter-spacing:-.005em;white-space:nowrap}
#menu .mpGo[aria-current="true"] .fn{font-weight:400}
#menu .mp .fs{font:400 11px/1.25 var(--sans);letter-spacing:.01em;color:var(--i45);white-space:nowrap}
#menu .mr .fs,#menu .cnt{font:400 11px/1.45 var(--sans);letter-spacing:.01em;color:var(--i45);font-variant-numeric:tabular-nums}
#menu .cnt{padding-right:var(--mp);white-space:nowrap}
#menu .mpGo .pr{margin-left:auto;padding-left:8px;font:400 13px/1 var(--sans);letter-spacing:.01em;color:var(--i70);
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* make next (v9-M): a 28 px ring in a 44 px target; pressed, it fills */
#menu .mpVote{flex:none;display:flex;align-items:center;justify-content:flex-end;gap:7px;min-width:48px;min-height:44px;
  padding:0 var(--mp) 0 8px;border-radius:var(--r-cap);color:var(--i70);transition:var(--tr-btn)}
#menu .mpVote .vi{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--i14);
  transition:background-color var(--dur-hover-out) var(--ease-ui),box-shadow var(--dur-hover-out) var(--ease-ui),color var(--dur-hover-out) var(--ease-ui)}
#menu .mpVote svg{display:block;width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
#menu .mpVote[aria-pressed="true"] .vi{background-color:var(--ink);box-shadow:none;color:var(--paper)}
/* in space --ink is the cream: the pressed ring reads graphite on it */
body.space #menu .mpVote[aria-pressed="true"] .vi{color:#1E2023}
#menu .mpVote .vc{font:400 12px/1 var(--sans);letter-spacing:.01em;color:var(--i45);font-variant-numeric:tabular-nums}
#menu .mnote{padding:4px var(--mp) 8px;font:400 12px/1.5 var(--sans);color:var(--i45)}
#menu .mnote.mcap{padding:0 var(--mp) 4px;font-size:11px;line-height:1.45;letter-spacing:.01em}
#menu .msep{height:1px;margin:8px var(--mp);border:0;background:var(--i14)}
#menu button.mi.mback{justify-content:flex-start;gap:4px;color:var(--i45)}
#menu button.mi{display:flex;width:100%;min-height:44px;justify-content:space-between;align-items:center;gap:14px;
  padding:10px var(--mp);border-radius:var(--r-btn);font:400 14px/1.4 var(--sans);letter-spacing:0;text-transform:none;
  color:var(--ink);text-align:left;transition:var(--tr-btn)}
#menu button.mi .v{display:flex;align-items:center;gap:8px;font-size:12px;letter-spacing:.01em;color:var(--i45);font-variant-numeric:tabular-nums}
/* Proposals opens inside the menu (back row "‹ Menu") */
#menu button.mi.mdrill .v::after{content:"›";content:"›"/"";font-size:17px;line-height:1;margin-top:-2px}
#menu .hd{padding:14px var(--mp) 4px;font:400 12px/1.4 var(--sans);letter-spacing:.01em;
  text-transform:none;color:var(--i70);display:flex;justify-content:space-between}
#menu .mview+.hd{padding-top:12px}

/* zoom − / + only: World and Norway live in the menu, their buttons stay as
   hooks. v9 R (owner 2026-10-18): quiet — on a desktop they are the zoom that
   needs no drag (keyboard, switch and head pointers), so they stay, light
   and shadowless; phones pinch, so there they go (media block below) */
#mapNav{display:flex;position:fixed;z-index:var(--z-chrome);right:var(--sp);bottom:calc(84px + env(safe-area-inset-bottom,0px));
  border-radius:var(--r-cap);box-shadow:var(--g-hair)}
#mapNav #worldBtn,#mapNav #norwayBtn{display:none}
#mapNav .icon{width:44px;height:44px;font:300 20px/1 var(--sans);color:var(--i45);transition:var(--tr-btn)}
#mapNav .icon+ .icon{border-left:1px solid var(--i14)}
/* no clip on the capsule (it cut the focus ring): each half carries its corners */
#zoomOut{border-radius:var(--r-cap) 0 0 var(--r-cap)}
#zoomIn{border-radius:0 var(--r-cap) var(--r-cap) 0}
body.hascard #mapNav,body.hist #mapNav{visibility:hidden}
/* C3: it waits for the card's exit (never a capsule popping over a card on
   its way out), then comes back by its material, hairline and glyphs —
   never its own opacity */
#mapNav{transition:box-shadow var(--t-ui) var(--ease-ui)}
body:has(#card.on,#card.leave) #mapNav{visibility:hidden;box-shadow:none}
body:has(#card.on,#card.leave) #mapNav::before,body:has(#card.on,#card.leave) #mapNav::after{opacity:0}
body:has(#card.on,#card.leave) #mapNav .icon{color:transparent;border-color:transparent}
/* orbit reset (B2 shows it only while orbit is live at a place): a round glass
   capsule in the map nav column — the zoom capsule's own right-hand column,
   stacked above it — with an ink needle (the map carries no red). At a place
   #mapNav steps away (≤ 4 hosts: pill, card, close, compass) and the compass
   keeps that column wherever the card leaves it free */
#compass{position:fixed;z-index:var(--z-chrome);right:calc(var(--sp) + env(safe-area-inset-right,0px));bottom:calc(136px + env(safe-area-inset-bottom,0px));
  width:44px;height:44px;display:grid;place-items:center;border-radius:var(--r-cap);color:var(--ink);transition:var(--tr-btn)}
#compass svg{width:22px;height:22px;transform:rotate(calc(var(--bearing,0) * -1deg))}
#compass .n{fill:var(--ink)}
#compass .s{fill:none;stroke:var(--ink);stroke-width:1.2}
/* desktop: the card holds the right edge, so the column steps to the map's
   own right edge — beside the card, on #mapNav's line */
body.hascard #compass{right:calc(var(--sp) + env(safe-area-inset-right,0px) + min(780px,57vw) + 12px);bottom:calc(84px + env(safe-area-inset-bottom,0px))}
/* the one-shot map picture under About/Terms (B3 fills it): a static blur on
   a still image, scaled so the soft edge stays off-screen */
#sheetShot{position:fixed;inset:0;width:100%;height:100%;object-fit:cover;z-index:var(--z-shot);
  pointer-events:none;visibility:hidden;opacity:0;filter:blur(16px) saturate(1.25);transform:scale(1.12);
  transition:opacity var(--t-ui),visibility 0s linear var(--t-ui)}
#sheetShot.on{visibility:visible;opacity:1;transition:opacity var(--t-ui)}

/* ---------- about / terms ----------
   paper, no frost of its own; once B3's snapshot is up it thins to show the
   blurred map through (never the live chrome) */
#about,#legal{position:fixed;inset:0;z-index:var(--z-page);background:var(--grain),var(--paper);
  display:block;overflow-y:auto;overscroll-behavior:contain;
  padding:clamp(60px,11vh,120px) var(--sp) var(--sp);
  visibility:hidden;pointer-events:none;transition:background-color var(--t-ui) var(--ease-ui)}
#about.on,#legal.on{visibility:visible;pointer-events:auto}
#sheetShot.on~:is(#about,#legal){background-color:var(--sheet)}
#about .w,#legal .w{max-width:58ch;margin:0 auto}
#about h2,#legal h2{font:300 clamp(32px,3.6vw,46px)/1.06 var(--sans);letter-spacing:-.03em;margin-bottom:24px}
/* v9 R: About opens on the script wordmark itself (red on paper), not a
   second Plex-caps "STØREN"; its clear space (0.40·H) is inside the box, so
   the ink lines up with the column by a negative margin of that clear space */
#about #aboutH{--wm-h:clamp(40px,4.4vw,60px);position:relative;width:calc(var(--wm-h) * 3.78826);height:calc(var(--wm-h) * 1.8);
  margin:calc(var(--wm-h) * -.4) 0 calc(var(--wm-h) * -.4 + 24px) calc(var(--wm-h) * -.4);color:var(--red)}
#about p,#legal p{font-size:16px;line-height:var(--lh-prose);color:var(--i70);margin-bottom:16px}
#about p.lead,#legal p.lead{color:var(--ink);font:300 20px/1.5 var(--sans);letter-spacing:-.005em;margin-bottom:22px}
#about h3,#legal h3{font:400 12px/1.4 var(--sans);letter-spacing:.08em;text-transform:uppercase;
  color:var(--i45);margin:36px 0 12px}
/* how a piece is made / studies: two columns, multiplied into the paper as a
   group (the open tween's transform isolates anything blended inside a .w child) */
.aboutFigs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin:6px 0 18px;mix-blend-mode:multiply}
.aboutFigs .af img{display:block;width:100%;aspect-ratio:1;object-fit:cover;background:var(--cream-2);border-radius:var(--r-thumb)}
.aboutFigs figcaption{font:400 12px/1.5 var(--sans);color:var(--i45);margin-top:6px}
/* full-ink emphasis (no synthetic bold: there is no 500/600 face) */
#legal .em{color:var(--ink)}
#about .src,#legal .src{font:400 11px/1.7 var(--tech);color:var(--i45);letter-spacing:.03em}
/* one close language on paper: the 13px word on a 60×44 target */
#aboutX,#legalX,#lbX,#drawerClose,#histX,#pinX{min-height:44px;min-width:60px;font:400 13px/1 var(--sans);
  letter-spacing:.01em;text-transform:none;color:var(--i70);transition:var(--tr-btn)}
/* the corner closes keep clear of the notch and the home indicator */
#aboutX,#legalX{position:fixed;top:calc(var(--sp) + env(safe-area-inset-top,0px));
  right:calc(var(--sp) + env(safe-area-inset-right,0px));z-index:var(--z-page-x)}

/* the water column, and the moment you break out of it onto land */
#tint{position:fixed;inset:0;z-index:var(--z-tint);pointer-events:none;opacity:0;background:#93AAA6;
  mix-blend-mode:multiply;will-change:opacity}
#surf{position:fixed;inset:0;z-index:var(--z-sky);pointer-events:none;opacity:0;background:#FBFAF7}
/* lightspeed (cinematic only). width/height are NOT optional: a canvas lays
   out at its intrinsic 2× size otherwise */
#warp{position:fixed;inset:0;width:100%;height:100%;z-index:var(--z-warp);pointer-events:none;display:none}
#warp.on{display:block}
body.warp :is(#mark,#hint,#readout,#menuBtn){--ink:var(--cream);--i70:rgba(237,230,214,.7);--i45:rgba(237,230,214,.5);color:var(--ink)}

/* panels that scroll are paper, never glass — a frost on a scroller would
   scroll away with it */
/* clear of the readout below it (B4); the creed steps away while it is up */
#pinPanel{position:fixed;left:calc(var(--sp) + env(safe-area-inset-left,0px));bottom:calc(var(--sp) + 100px + env(safe-area-inset-bottom,0px));z-index:var(--z-panel);
  width:min(300px,84vw);background:var(--grain),var(--paper);border-radius:var(--r-card);box-shadow:var(--g-hair),var(--sh-2);padding:18px 20px;
  visibility:hidden;pointer-events:none}
#pinPanel.on{visibility:visible;pointer-events:auto}
#pinX{position:absolute;top:2px;right:6px}
#pinPanel .py{font:400 11px/1 var(--tech);letter-spacing:.14em;text-transform:uppercase;color:var(--i45);margin-bottom:8px;padding-right:64px}
#pinPanel .pc{font:400 12px/1.7 var(--tech);letter-spacing:.06em;font-variant-numeric:tabular-nums;margin-bottom:6px}
#pinPanel .pd{font-size:13px;line-height:1.55;color:var(--i70);margin-bottom:10px}
#pinPanel .pn{font-size:12px;line-height:1.55;color:var(--i45);border-top:1px solid var(--i14);padding-top:9px;margin-bottom:10px}
#pinPanel .pvn{display:block;font:400 12px/1.5 var(--sans);color:var(--i70);margin-bottom:8px;font-variant-numeric:tabular-nums}
#pinPanel .pv,#pinPanel .pm{font-size:13px;line-height:1.55;color:var(--ink);margin-bottom:8px}
/* every action one language (B4): mono words on a hairline, 44px tall */
#pinPanel .pa{display:flex;flex-wrap:wrap;gap:4px 16px;margin-bottom:10px}
#pinPanel .pa button,#pinPanel #pinVote{min-height:44px;font:400 11px/1 var(--tech);letter-spacing:.1em;text-transform:uppercase;color:var(--i70);
  text-decoration:underline 1px var(--i28);text-underline-offset:5px;padding:0 2px;transition:var(--tr-btn)}
#pinPanel #pinVote[disabled]{opacity:.45;cursor:default}
/* pin mode: the one instruction while it is up, on a paper capsule (no host) */
#pinMode{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(var(--sp) + 40px + env(safe-area-inset-bottom,0px));z-index:var(--z-panel);
  display:flex;align-items:center;gap:12px;padding:0 4px 0 18px;min-height:48px;max-width:calc(100vw - 2*var(--sp));
  background:var(--grain),var(--paper);border-radius:var(--r-cap);box-shadow:var(--g-hair),var(--sh-2);font:400 13px/1.3 var(--sans);color:var(--ink)}
#pinCancel{min-height:44px;padding:0 16px;border-left:1px solid var(--i14);border-radius:0 var(--r-cap) var(--r-cap) 0;
  font:400 13px/1 var(--sans);color:var(--i70);transition:var(--tr-btn)}
.pinmk{cursor:pointer;background:none;border:0;padding:0}
.pinmk svg{width:22px;height:22px;overflow:visible}
.pinmk svg circle{stroke:var(--ink);fill:none;stroke-width:1.2}
.pinmk svg .ct{fill:var(--ink);stroke:none}

/* ---------- the card ---------- heading, scrolling body, purchase dock */
/* #card = the glass frame, never scrolls; #cardMount = the rows. hidden +
   overscroll-behavior:contain (not clip, v9 A fix r1): as a scroll container
   its contents rasterise pixel-snapped — top is a vh clamp, so the card can
   sit at a fractional y and with clip every inner hairline would antialias
   across 3 device rows instead of 2 */
/* desktop: it hangs from the close pill's row, 12px below it */
#card{position:fixed;z-index:var(--z-card);left:auto;right:var(--sp);top:calc(clamp(20px,4.5vh,44px) + 56px + env(safe-area-inset-top,0px));bottom:auto;
  width:min(780px,57vw);max-height:calc(100dvh - clamp(20px,4.5vh,44px) - 56px - var(--sp));display:none;
  grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);gap:0;align-items:stretch;
  padding:8px;overflow:hidden;overscroll-behavior:contain;border-radius:var(--r-card);box-shadow:var(--g-hair),var(--sh-3)}
/* C3: rest states — it enters from the edge facing its mark and leaves back
   toward it by the UI MOTION region (app.js); never the host's opacity
   (a backdrop root). .leave = closing: on screen, untouchable */
#card.on,#card.leave{display:grid}
#card.leave:not(.on){pointer-events:none}
/* opaque paper mount, concentric (20 = 12 + 8), a breath of NW frame shadow */
#cardMount{display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto;
  gap:0;align-items:stretch;min-width:0;min-height:0;background:var(--grain),var(--paper);border-radius:var(--r-inner);
  box-shadow:inset 0 0 0 .5px rgba(46,40,30,.14),inset 1px 2px 3px rgba(46,40,30,.06)}
/* the garment and the history never speak at once — reading one puts the other away */
body.hist #card{visibility:hidden;pointer-events:none}
/* C3: .away holds it on screen while it steps away (UI MOTION, full motion only) */
body.hist #card.away{visibility:visible}
#placeHeading{padding:22px 26px 18px;display:flex;justify-content:space-between;align-items:flex-start;gap:var(--s4);
  border-bottom:1px solid var(--i14)}
#placeHeading h2{font:300 clamp(30px,3vw,42px)/1.04 var(--sans);letter-spacing:-.03em}
#placeHeading .cd{font:400 12px/1.6 var(--tech);letter-spacing:.02em;color:var(--i70);margin-top:8px;font-variant-numeric:tabular-nums}
.placePrice{text-align:right;flex-shrink:0;font:400 17px/1.4 var(--sans);letter-spacing:-.01em;padding-top:4px;font-variant-numeric:tabular-nums}
.placePrice span{display:block;font:400 11px/1.5 var(--sans);letter-spacing:.01em;color:var(--i45);margin-top:4px}
#cardBody{display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,1fr);gap:24px;
  padding:24px 26px;overflow:auto;overscroll-behavior:contain;min-height:0;scrollbar-width:thin;
  scrollbar-color:var(--i28) transparent;align-items:start}
#cardBody:focus-visible{outline-offset:-4px;box-shadow:none}
/* text sliding under the dock fades instead of being sliced mid-line (review
   r1) — the body's own 24 px foot padding keeps the last line clear of it */
#cardBody{-webkit-mask-image:linear-gradient(#000 calc(100% - 20px),transparent);mask-image:linear-gradient(#000 calc(100% - 20px),transparent)}
/* the strip's edge fade lives on the non-scrolling wrapper */
.figwrap{position:relative;min-width:0}
/* only a gallery has a strip to fade (on a drawing it notched the frame) */
.figwrap:has(.figure.live)::after{content:"";position:absolute;right:-6px;bottom:8px;width:28px;height:48px;
  pointer-events:none;background:linear-gradient(to right,transparent,var(--paper) 75%)}
/* no base clip-path: clearProps would snap it back after the reveal */
.figure{position:relative;aspect-ratio:3/4;background:var(--cream-2);border:0;border-radius:var(--r-thumb);overflow:hidden;
  perspective:1200px}
.figure.live{cursor:pointer;outline-offset:3px}
.figure.live::after{content:"↗";position:absolute;right:10px;bottom:10px;display:grid;place-items:center;
  width:30px;height:30px;background:rgba(246,242,232,.92);border-radius:50%;box-shadow:var(--g-hair),var(--sh-1);font:400 17px/1 var(--sans);pointer-events:none}
/* contain: studies show whole on the ground, never cropped (a step
   cross-fades over img.xf, the old one beneath — C3) */
.figure img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  backface-visibility:hidden}
.figure .dw{position:absolute;inset:0;display:grid;place-items:center}
.figure .dw svg{width:92%;height:92%}
.figure .dw img{position:static;inset:auto;display:block;width:92%;height:92%;object-fit:contain}
.figure.study{aspect-ratio:4/3}
/* the renders' own 4:5 frame, filled (the square close-ups lose 10 % a side);
   width from the height budget at each breakpoint */
#cardBody .figure.live{aspect-ratio:4/5;margin-inline:auto}
.figure.live img{object-fit:cover}
.figure.live img.fit{object-fit:contain;padding:10%;box-sizing:border-box}
.figure.study .dw img{width:96%;height:auto;max-height:88%}
.figcap{margin-top:10px;min-height:33px;font:400 11px/1.5 var(--sans);letter-spacing:.01em;text-indent:0;
  text-transform:none;color:var(--i70);text-align:left}

/* gallery */
.strip{display:flex;gap:6px;margin:0 -6px;padding:6px 6px 8px;overflow-x:auto;scrollbar-width:thin;
  scroll-snap-type:x proximity;scroll-padding-inline:6px;-webkit-overflow-scrolling:touch}
.strip button{flex:0 0 44px;height:48px;aspect-ratio:1;border:0;border-radius:var(--r-thumb);background:var(--cream-2);
  box-shadow:inset 0 0 0 1px var(--i14);padding:0;overflow:hidden;position:relative;scroll-snap-align:start;transition:var(--tr-btn)}
.strip button img{width:100%;height:100%;object-fit:cover;opacity:.62;transition:opacity var(--t-hover)}
.strip button.sel img{opacity:1}
.strip button.sel{box-shadow:inset 0 0 0 1.5px var(--ink)}
.kind{position:absolute;left:0;right:0;bottom:0;font:400 11px/1.4 var(--sans);letter-spacing:.01em;text-indent:0;
  text-transform:none;text-align:center;background:rgba(246,242,232,.9);color:var(--i70);overflow:hidden}
.galnav{display:flex;justify-content:space-between;align-items:center;margin-top:8px;min-height:36px}
.galnav button{font:400 12px/1 var(--sans);letter-spacing:.01em;text-transform:none;color:var(--i70);padding:10px 8px;margin:0 -8px;min-height:36px;
  transition:var(--tr-btn)}
.galnav span{font:400 11px/1 var(--tech);letter-spacing:.02em;color:var(--i70);font-variant-numeric:tabular-nums}

/* lightbox: opaque paper, the image on its own small shadow */
#lb{position:fixed;inset:0;z-index:var(--z-lb);background:var(--grain),var(--paper);display:grid;
  place-items:center;padding:clamp(40px,7vh,90px) var(--sp);
  visibility:hidden;pointer-events:none}
#lb.on{visibility:visible;pointer-events:auto}
/* one cell: a step's old picture (img.xf, C3) stacks beneath the new one */
#lb img{grid-area:1/1;max-width:100%;max-height:78vh;object-fit:contain;border-radius:var(--r-thumb);box-shadow:var(--g-hair),var(--sh-2)}
#lbCap{position:absolute;left:0;right:0;bottom:calc(clamp(20px,4vh,44px) + env(safe-area-inset-bottom,0px));text-align:center;
  padding:0 60px;font:400 12px/1.6 var(--sans);letter-spacing:.01em;text-indent:0;text-transform:none;color:var(--i70)}
#lbX{position:absolute;top:calc(var(--sp) + env(safe-area-inset-top,0px));right:calc(var(--sp) + env(safe-area-inset-right,0px))}
/* Prev/Next: paper capsules ABOVE the image (its open animation's scale
   makes the img a stacking context that buried a plain Prev, review r1) */
.lbArrow{position:absolute;top:50%;z-index:1;transform:translateY(-50%);width:48px;height:48px;border-radius:var(--r-cap);
  display:grid;place-items:center;color:var(--ink);background:rgba(246,242,232,.9);box-shadow:var(--g-hair),var(--sh-1);
  transition:var(--tr-btn)}
.lbArrow svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
#lbPrev{left:max(18px,calc(var(--sp) / 2 + env(safe-area-inset-left,0px)))}
#lbNext{right:max(18px,calc(var(--sp) / 2 + env(safe-area-inset-right,0px)))}
/* where the photo fills the width they sit inset on it, on their plate */
@media(max-width:900px){
  #lbPrev{left:calc(var(--sp) + 10px + env(safe-area-inset-left,0px))}
  #lbNext{right:calc(var(--sp) + 10px + env(safe-area-inset-right,0px))}
}

/* history markers (map markers: MapLibre owns their transform — no press scale) */
.hm{cursor:pointer;display:flex;align-items:center;gap:7px;white-space:nowrap}
.hm b{width:22px;height:22px;border-radius:50%;border:1px solid var(--ink);background:var(--paper);
  display:grid;place-items:center;font:400 11px/1 var(--tech);flex:0 0 auto;transition:background-color var(--t-hover),color var(--t-hover)}
.hm .hl{font:400 11px/1 var(--tech);letter-spacing:.1em;text-transform:uppercase;color:var(--i70);
  background:var(--plate);border-radius:var(--r-cap);box-shadow:var(--g-hair);padding:5px 9px;opacity:0;transition:opacity var(--dur-exit) var(--ease-ui)}
.hm.sel b{background:var(--ink);color:var(--cream)}
/* the point being read wears a halo — cream keyline, then soft graphite */
.hm.sel b{box-shadow:0 0 0 3px rgba(var(--cream-rgb),.86),0 0 0 4px rgba(46,49,52,.22)}
.hm.sel .hl{opacity:1;color:var(--ink);transition-duration:var(--dur-card)}

/* history panel: reads on the left; the card holds the right. Paper — it scrolls */
#histPanel{position:fixed;left:calc(var(--sp) + env(safe-area-inset-left,0px));top:50%;transform:translateY(-50%);z-index:var(--z-panel);
  width:min(360px,88vw);background:var(--grain),var(--paper);border-radius:var(--r-card);box-shadow:var(--g-hair),var(--sh-3);
  padding:clamp(20px,2.6vw,30px);
  visibility:hidden;pointer-events:none}
#histPanel.on{visibility:visible;pointer-events:auto}
/* C3: sheets and panels fade (and stagger in) by the UI MOTION region in
   app.js; .leave holds one on screen, untouchable, while it fades out */
:is(#about,#legal,#lb,#pinPanel,#histPanel).leave{visibility:visible}
#histPanel .hy{font:400 11px/1 var(--tech);letter-spacing:.14em;color:var(--i45);margin-bottom:9px;font-variant-numeric:tabular-nums}
#histPanel h4{font:300 30px/1.12 var(--sans);letter-spacing:-.02em;margin-bottom:12px}
#histPanel p{font-size:14px;line-height:1.65;color:var(--i70);margin-bottom:14px}
#histPanel .hw{font:400 11px/1.5 var(--tech);letter-spacing:.08em;color:var(--ink);
  border-top:1px solid var(--i14);padding-top:11px;margin-bottom:7px}
#histPanel .hs{font:400 11px/1.5 var(--tech);letter-spacing:.06em;color:var(--i45)}
#histPanel .hnav{display:flex;justify-content:space-between;align-items:center;margin-top:var(--s4);
  border-top:1px solid var(--i14);padding-top:11px}
#histPanel .hnav button{font:400 11px/1 var(--tech);letter-spacing:.1em;text-transform:uppercase;color:var(--i70);transition:var(--tr-btn)}
#histPanel .hnav span{font:400 11px/1 var(--tech);color:var(--i45);font-variant-numeric:tabular-nums}
/* the word on the panel's first line, its right edge on the padding */
#histX{position:absolute;top:calc(clamp(20px,2.6vw,30px) - 16px);right:calc(clamp(20px,2.6vw,30px) - 14px)}
body.hascard #hint{opacity:0!important;visibility:hidden}

/* ---------- facts ---------- */
.facts{position:relative;min-width:0}
.facts p{font-size:14px;line-height:var(--lh-body);color:var(--i70);margin-bottom:12px;max-width:none}
.facts p.ev{color:var(--ink)}
.facts p.sm{font-size:12px;line-height:1.6;color:var(--i45);margin-bottom:4px}
.facts p.area{font:400 11px/1.6 var(--tech);letter-spacing:.02em;color:var(--i45);
  border-left:1px solid var(--i14);padding-left:10px;margin:8px 0 0}
.facts .productIntro{font-size:19px;line-height:1.4;letter-spacing:-.01em;color:var(--ink);font-weight:300;margin-bottom:18px}
.facts .productDelivery{font-size:12px;color:var(--i70);margin-bottom:20px}
/* the always-visible lead (B4 IA): garment + composition, commission + numbering, delivery */
.facts .lead{margin-bottom:6px}
.facts .productCommission{font-size:13px;color:var(--ink);margin-bottom:8px}
table.measure{border-collapse:collapse;font:400 12px/1.6 var(--sans);color:var(--i70);margin:6px 0 12px;font-variant-numeric:tabular-nums}
table.measure caption{text-align:left;color:var(--i45);padding-bottom:4px}
table.measure th,table.measure td{padding:3px 16px 3px 0;text-align:left;font-weight:400;border-bottom:1px solid var(--i14)}
table.measure th{color:var(--i45)}
/* drawing cards: "Make this next" (primary .buy look), Withdraw (quiet) */
.vote{margin:16px 0 4px;padding-top:14px;border-top:1px solid var(--i14)}
.vBtn{min-height:44px;padding:0 20px;border-radius:var(--r-btn);font:400 14px/1 var(--sans);color:var(--ink);
  box-shadow:inset 0 0 0 1px var(--i28);transition:var(--tr-btn)}
#voteBtn{background:var(--ink);color:var(--cream);box-shadow:inset 1px 1px 0 rgba(255,255,255,.12),var(--sh-1)}
.vBtn[disabled]{opacity:.45;cursor:default}
.facts .vDone{color:var(--ink);margin-bottom:8px}
.facts .vPromise,.facts .vCount,.facts .vNote,.facts .vMsg{font-size:12px;line-height:1.55;margin:8px 0 0}
.facts .vMsg{color:var(--ink)}
.facts .placeStory{margin-top:22px;border-top:1px solid var(--i14)}
.facts p.spec{font-size:14px;line-height:var(--lh-body);color:var(--ink);margin-bottom:12px}
.facts p.thanks{color:var(--ink);margin-top:10px}
/* every disclosure on the card is a .mapMeta inside .facts */
.mapMeta{margin-top:8px;border-top:1px solid var(--i14);padding-top:0;color:var(--i45)}
.mapMeta summary{list-style:none;min-height:44px;padding:14px 6px;margin:0 -6px;cursor:pointer;font:400 13px/1.4 var(--sans);
  letter-spacing:.01em;color:var(--i70);text-transform:none;display:flex;justify-content:space-between;align-items:center}
.mapMeta summary::-webkit-details-marker{display:none}
.mapMeta summary::after{content:"+";font-size:16px;font-weight:300;line-height:1}
.mapMeta[open] summary::after{content:"−"}
/* the two text-style actions inside "The place" */
.ghost{display:block;width:fit-content;min-height:40px;margin-top:8px;padding:10px 0;font:400 12px/1.4 var(--sans);
  letter-spacing:.01em;text-transform:none;text-align:left;color:var(--i70);border-bottom:1px solid var(--i14);transition:var(--tr-btn)}
.ghost.on{color:var(--ink);border-color:var(--ink)}
/* the waitlist — one quiet line under the promise */
.wl{margin-top:16px}
.wlLbl{display:block;font:400 13px/1.5 var(--sans);letter-spacing:0;text-transform:none;color:var(--ink);margin-bottom:8px}
.wlLbl .wlNote{display:block;font-size:12px;color:var(--i45)}
.wlRow{display:flex;flex-wrap:wrap;gap:8px;align-items:stretch}
/* 16px: iOS Safari zooms the whole page on focus of any smaller input */
.wlRow input{flex:1 1 120px;min-width:0;min-height:44px;background:none;border:0;border-bottom:1px solid var(--i28);border-radius:0;
  font:400 16px/1.4 var(--sans);color:var(--ink);padding:6px 1px}
.wlRow input:focus-visible{outline:none;box-shadow:none;border-bottom-color:var(--ink)}
.wlRow button{min-height:44px;font:400 13px/1.4 var(--sans);letter-spacing:.01em;text-transform:none;color:var(--ink);
  border:1px solid var(--i28);border-radius:var(--r-btn);padding:0 16px;transition:var(--tr-btn)}
.wlMsg{font:400 12px/1.6 var(--sans);color:var(--i45);margin-top:8px;min-height:17px}
/* quiet in-copy links to the terms panel */
.tlink{font:inherit;color:var(--i70);text-decoration:underline;text-underline-offset:2px;transition:color var(--t-ui)}
/* facts the site does not yet have — visibly unfinished, never faked */
.tbd{border-bottom:1px dashed var(--i45);color:var(--i45);font-family:var(--tech);font-size:.92em;padding:0 2px}

/* ---------- purchase dock ---------- */
#purchaseDock{padding:16px 26px 20px;border-top:1px solid var(--i14);display:flex;
  justify-content:space-between;align-items:end;gap:18px}
/* A4: sold out — struck sizes, one sentence, the waitlist */
#purchaseDock.sold{flex-direction:column;align-items:stretch;gap:10px}
#purchaseDock.sold .wl{margin-top:0}
.soldLine{font:400 13px/1.5 var(--sans);color:var(--ink);margin:0}
.sizeLabel{font:400 12px/1.4 var(--sans);letter-spacing:.01em;margin-bottom:8px;color:var(--i70)}
.sizes{display:flex;gap:7px}
.sizeRow{display:flex;align-items:center;gap:14px}
.sizeGuide{min-height:44px;font-size:12px}
.sizes button{width:44px;height:44px;border:1px solid var(--i28);border-radius:var(--r-btn);font:400 14px/1 var(--sans);transition:var(--tr-btn)}
.sizes button.sel{background:var(--ink);color:var(--cream);border-color:var(--ink)}
.sizes button[disabled]{color:var(--i28);border-style:dashed;border-color:var(--i14);cursor:default;text-decoration:line-through}
/* the disabled Commission button's live reason (F037) */
/* v9 R: "Choose your size" above the chips already says it — the status
   ("Select a size to continue", "Size S selected.") stays for assistive tech
   (#pre's description, role=status), never as a second visible line */
.sizeStatus{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* B13: a struck chip's reason, in text */
.sizeSpoken{font:400 11px/1.4 var(--sans);color:var(--i70);margin:7px 0 0}
.purchaseAction{flex:1;max-width:300px;text-align:right}
.purchaseNote{font:400 11px/1.4 var(--sans);letter-spacing:.01em;color:var(--i70);margin-bottom:8px}
/* the one PRIMARY treatment for every commit action */
.buy{margin-top:16px;min-height:44px;padding:0 26px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--ink);border-radius:var(--r-btn);background:var(--ink);color:var(--cream);
  font:400 14px/1 var(--sans);letter-spacing:.005em;text-transform:none;transition:var(--tr-btn);
  box-shadow:inset 1px 1px 0 rgba(255,255,255,.12),var(--sh-1)}
.buy[disabled]{opacity:.32;cursor:not-allowed}
/* Vipps (Tier 2b): never solid, Continue stays primary */
.buy.sec{border-color:var(--i28);color:var(--ink);background:none;box-shadow:none}
.purchaseAction .buy{width:100%;margin:0;padding:12px 16px;min-height:44px;
  font:400 14px/1.4 var(--sans);text-transform:none;text-indent:0}
.purchaseAction .buy[disabled]{opacity:1;background:var(--cream-2);color:var(--i45);border-color:var(--i14);box-shadow:none}
/* fades by material + words, never the host; base leaves visibility out */
#cardClose{position:fixed;top:calc(clamp(20px,4.5vh,44px) + env(safe-area-inset-top,0px));
  right:calc(var(--sp) + env(safe-area-inset-right,0px));z-index:var(--z-close);min-height:44px;padding:0 18px;
  border-radius:var(--r-cap);font:400 13px/1 var(--sans);letter-spacing:.01em;text-transform:none;color:transparent;
  visibility:hidden;pointer-events:none;
  /* C3: in on the card's time, out on the exit token */
  transition:color var(--dur-exit) var(--ease-standard),transform var(--dur-press) var(--ease-ui),visibility 0s linear var(--dur-exit)}
#cardClose::before,#cardClose::after{opacity:0;transition:background-color var(--dur-hover-out) var(--ease-ui),opacity var(--dur-exit) var(--ease-standard)}
#cardClose.on{color:var(--i70);visibility:visible;pointer-events:auto;transition:color var(--dur-hover-out) var(--ease-ui),transform var(--dur-press) var(--ease-ui)}
#cardClose.on::before,#cardClose.on::after{opacity:1;transition:background-color var(--dur-hover-out) var(--ease-ui),opacity var(--dur-card) var(--ease-ui)}

/* ---------- drawer ---------- */
/* opens in --t-move, visible at once; closes in --t-ui and hides as the slide
   ends. NEVER list visibility in the open transition (RM's .01ms holds
   "hidden" a frame — the H1 bug; under RM the children's visibility is kept
   out of every transition list by the RM block at the end of this file).
   Host = floating glass sheet, #drawerBody = the scrolling paper mount;
   phones: one opaque sheet */
#drawer{--dr:max(12px,env(safe-area-inset-right,0px));position:fixed;top:max(12px,env(safe-area-inset-top,0px));right:var(--dr);
  bottom:max(12px,env(safe-area-inset-bottom,0px));width:calc(var(--drawer-w) - 24px);padding:8px;border-radius:var(--r-card);
  z-index:var(--z-drawer);transform:translateX(calc(100% + var(--dr) + 12px));visibility:hidden;
  transition:transform var(--t-ui) var(--ease-out),visibility 0s linear var(--t-ui)}
#drawer.on{transform:none;visibility:visible;transition:transform var(--t-move) var(--ease-out)}
/* position:relative keeps #drawerClose scrolling with the content, as before */
#drawerBody{--dbp:clamp(20px,2.6vw,32px);position:relative;height:100%;overflow-y:auto;overscroll-behavior:contain;container-type:inline-size;
  padding:64px var(--dbp) calc(24px + env(safe-area-inset-bottom,0px));
  background:var(--grain),var(--paper);border-radius:var(--r-inner);
  box-shadow:inset 0 0 0 .5px rgba(46,40,30,.14);scrollbar-width:thin;scrollbar-color:var(--i28) transparent;
  /* keeps a focused field clear of the sticky .cka and the iOS keyboard */
  scroll-padding-bottom:96px}
#drawer h3{font:300 34px/1.08 var(--sans);letter-spacing:-.025em;margin-bottom:8px}
#drawer .cd{font:400 11px/1.7 var(--tech);letter-spacing:.02em;color:var(--i70);margin-bottom:14px;font-variant-numeric:tabular-nums}
#drawer dt{font:400 12px/1.4 var(--sans);letter-spacing:.01em;text-transform:none;color:var(--i70);margin-bottom:6px}
#drawer dd{font-size:15px;margin-bottom:var(--s4);line-height:1.55;font-variant-numeric:tabular-nums}
#drawerClose{position:absolute;top:12px;right:12px}
/* checkout: the same instrument language — labels over quiet rule-lines */
#drawer .fld{margin-bottom:13px}
#drawer .fld label{display:block;font:400 12px/1.4 var(--sans);letter-spacing:.01em;text-transform:none;color:var(--i70);margin-bottom:6px}
#drawer .fld input{width:100%;min-height:44px;background:none;border:0;border-bottom:1px solid var(--i28);border-radius:0;
  padding:7px 0;font:400 16px/1.4 var(--sans);color:var(--ink);transition:border-color var(--t-ui)}
#drawer .fld input:not([type=checkbox]):focus-visible{outline:none;box-shadow:none;border-bottom-color:var(--ink)}
#drawer .fld input[aria-invalid="true"]{border-color:var(--rust);border-width:2px}
/* the terms-acceptance row (F033) is a checkbox + label, not a text field */
#drawer .fld.terms{margin-top:2px}
#drawer .fld.terms label{display:flex;align-items:flex-start;gap:10px;
  font:400 13px/1.5 var(--sans);letter-spacing:0;text-transform:none;color:var(--i70)}
#drawer .fld.terms input{width:20px;height:20px;min-height:0;flex:0 0 auto;margin:0;border-bottom:0;accent-color:var(--ink)}
#drawer .fld select{width:100%;min-height:44px;font:400 16px/1.4 var(--sans);color:var(--ink);background:none;border:0;
  border-bottom:1px solid var(--i28);border-radius:0}
#drawer .frow{display:flex;gap:16px}
.dSizes{display:flex;gap:7px}
.dSizes button{width:44px;height:44px;border-radius:var(--r-btn);box-shadow:inset 0 0 0 1px var(--i28);font:400 14px/1 var(--sans);transition:var(--tr-btn)}
.dSizes button.sel{background:var(--ink);color:var(--cream);box-shadow:none}
.dSizes button[disabled]{color:var(--i28);box-shadow:inset 0 0 0 1px var(--i14);text-decoration:line-through;cursor:default}
#drawer .dNext{margin:4px 0 18px;padding-top:14px;border-top:1px solid var(--i14)}
#drawer .dNext h4{font:400 13px/1.4 var(--sans);margin-bottom:8px}
#drawer .dNext ol{padding-left:18px;font-size:13px;line-height:1.6;color:var(--i70)}
#drawer .dNext li{margin-bottom:4px}
#drawer .dNextPre,#drawer .dDest{font-size:13px;line-height:1.55;color:var(--i70);margin-bottom:8px}
#drawer .dDest .dTot{display:block;font-size:15px;color:var(--ink);margin-bottom:4px;font-variant-numeric:tabular-nums}
/* the acceptance, the total and Continue stay pinned to the foot of the
   paper mount, in view the moment it opens (B4). The sticky edge is inset by
   #drawerBody's bottom padding, so bottom is minus that padding; the band
   bleeds to the mount's edges on the grained paper */
#drawer .dAct{position:sticky;bottom:calc(-24px - env(safe-area-inset-bottom,0px));z-index:1;margin:0 calc(-1 * var(--dbp));
  padding:12px var(--dbp) calc(16px + env(safe-area-inset-bottom,0px));background:var(--grain),var(--paper);border-top:1px solid var(--i14)}
/* the copy above fades into the band rather than being cut by its edge */
#drawer .dAct::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:22px;pointer-events:none;
  background:linear-gradient(rgba(246,242,232,0),var(--paper))}
#drawer .dAct #confirm{width:100%}
#drawer .dAct #dMsg{min-height:0}
#drawer .frow .fld{flex:1 1 0;min-width:0}
#ckSum{font:400 12px/1.6 var(--sans);letter-spacing:.01em;color:var(--i70);font-variant-numeric:tabular-nums;
  background:rgba(46,49,52,.035);border-radius:var(--r-btn);padding:10px 13px;margin-bottom:18px}
#ckMsg,#dMsg{font-size:12px;line-height:1.5;color:var(--ink);min-height:18px;margin:8px 0 0}
/* dStep1's only .fld needs its own margin */
#vippsEmailFld{margin-top:16px}
/* the actions stay pinned to the foot of the scroller */
#drawer .cka{display:flex;gap:18px;align-items:center;margin-top:10px;
  position:sticky;bottom:0;background:var(--grain),var(--paper);padding:12px 0 calc(12px + env(safe-area-inset-bottom,0px))}
#drawer .cka .buy{margin-top:0}
#drawer .buy{font:400 14px/1.4 var(--sans);text-transform:none;text-indent:0;min-height:44px}
#ckBack{min-height:44px;font:400 13px/1 var(--sans);letter-spacing:.01em;text-transform:none;color:var(--i70);
  text-decoration:underline 1px var(--i14);text-underline-offset:6px;padding:6px 0;transition:var(--tr-btn)}
.ckno{font:300 26px/1.2 var(--sans);letter-spacing:-.015em;margin:4px 0 14px;font-variant-numeric:tabular-nums}
.ckp{font-size:13px;line-height:1.62;color:var(--i70);margin-bottom:12px}
.note{font-size:12px;line-height:1.6;color:var(--i70);border-top:1px solid var(--i14);padding-top:14px;margin-top:20px}

/* glass capsule on desktop (4th host, only without a card); plate on phones;
   always clear of the attribution row */
#hint{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(max(var(--sp),42px) + env(safe-area-inset-bottom,0px));z-index:var(--z-chrome);
  max-width:46vw;padding:9px 18px;border-radius:var(--r-cap);font:400 12px/1.5 var(--sans);letter-spacing:.01em;text-indent:0;text-transform:none;color:var(--i70);
  pointer-events:none;text-align:center;text-wrap:balance;transition:color .5s,visibility 0s}
#hint:empty{visibility:hidden}
/* on/off by its material and its words, never the host's opacity (a faded
   host is a backdrop root: the frost popped in at the end, review r1) */
#hint.off{color:transparent!important;visibility:hidden;transition:color .5s,visibility 0s linear .5s}
#hint.off::before,#hint.off::after{opacity:0}

/* ---------- the circular mark (v9 R, approved 2026-10-08) ----------
   R fix r1 (review r1, measured on the harness Chrome = Graphite/Metal):
   drawn from exact-coverage alpha masks of the master path, never as inline
   SVG. The ring's tips taper to nothing and the slash is 0.61 of 42 units;
   the GPU rasteriser broke the tips into separate specks at EVERY size from
   26 to 44 px whatever the delivery (inline <use>, <img> SVG, SVG mask) — a
   bigger mark only thickened the slash. The masks hold the true area
   coverage at the device size (scripts/render-mark-masks.cjs: master path
   verbatim, 16× supersampled, box-averaged), so they draw 1:1: tips taper,
   the slash stays one line. Sizes: 30 px a drawing's map mark + the Oslo
   gathering, 34 px the made piece + the Menu pill (slash ~1 device px at
   2×); ×1.4 when a menu row lifts it. At 1× the slash is a sub-pixel
   hairline and the tips shorten — the package README's accepted "terminal
   erosion", not break-up. Colour = currentColor; the box is the ink box
   (15 15 42.603 42, centred), never stretched */
.stm{display:block;position:relative;flex:none;width:30px;height:30px}
.stm::before{content:"";position:absolute;inset:0;background:currentColor;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;
  -webkit-mask-image:-webkit-image-set(url(img/identity/mark/mark-30@1x.png) 1x,url(img/identity/mark/mark-30@2x.png) 2x,url(img/identity/mark/mark-30@3x.png) 3x);mask-image:image-set(url(img/identity/mark/mark-30@1x.png) 1x,url(img/identity/mark/mark-30@2x.png) 2x,url(img/identity/mark/mark-30@3x.png) 3x)}
#menuBtn .stm::before,.mk.live .stm::before{-webkit-mask-image:-webkit-image-set(url(img/identity/mark/mark-34@1x.png) 1x,url(img/identity/mark/mark-34@2x.png) 2x,url(img/identity/mark/mark-34@3x.png) 3x);mask-image:image-set(url(img/identity/mark/mark-34@1x.png) 1x,url(img/identity/mark/mark-34@2x.png) 2x,url(img/identity/mark/mark-34@3x.png) 3x)}

/* ---------- map marks ---------- no position on .mk: MapLibre's absolute must win */
/* C3: a mark and its name come and go on one curve (card time in, exit token out) */
.mk{cursor:pointer;width:34px;height:34px;display:grid;place-items:center;color:var(--red);transition:opacity var(--dur-exit) var(--ease-ui)}
.mk[aria-hidden="false"]{transition-duration:var(--dur-card)}
/* your own pins step aside and back on the same curve */
.maplibregl-marker.pinmk{transition:opacity var(--dur-exit) var(--ease-ui)}
.maplibregl-marker.pinmk[aria-hidden="false"]{transition-duration:var(--dur-card)}
/* the Oslo places travel out of their gathering (app.js writes --tr: the
   children move, never .mk); travelling, the opacity follows the zoom */
.mk>*{translate:var(--tr,none)}
.mk.trav{transition:none}
/* a paper halo (no plate, no redraw): the thin top of the ring and the slash
   stay legible over roads and contours */
.mk .stm{filter:drop-shadow(0 0 1px rgba(246,242,232,.95)) drop-shadow(0 0 2.5px rgba(246,242,232,.75));
  transition:transform var(--dur-hover-out) var(--ease-ui)}
.mk .lbl{position:absolute;left:36px;top:50%;transform:translateY(-50%);white-space:nowrap;
  font:400 12px/1.3 var(--sans);letter-spacing:.02em;text-transform:none;color:var(--ink);
  background:rgba(246,242,232,.9);padding:5px 10px;border-radius:var(--r-cap);box-shadow:var(--g-hair),var(--sh-1);
  opacity:0;transition:opacity var(--dur-exit) var(--ease-ui);pointer-events:none}
.mk:focus-visible .lbl,.mk.near .lbl,.mk.gather .lbl{opacity:1;transition-duration:var(--dur-card)}
.mk.live .stm{width:34px;height:34px}
.mk.dimmed{opacity:.22}
/* from z ≥ 9 every place name stands beside its mark (B2 sets .named) */
.mk.named .lbl{opacity:1;transition-duration:var(--dur-card)}
/* the hovered menu row lifts its mark: the .stm, never .mk (MapLibre owns its
   transform); the lifted mask is the ×1.4 raster, so the lift is 1:1 too */
.mk.lift .stm{transform:scale(1.4);transition-duration:var(--dur-hover-in)}
.mk.lift .stm::before{-webkit-mask-image:-webkit-image-set(url(img/identity/mark/mark-42@1x.png) 1x,url(img/identity/mark/mark-42@2x.png) 2x,url(img/identity/mark/mark-42@3x.png) 3x);mask-image:image-set(url(img/identity/mark/mark-42@1x.png) 1x,url(img/identity/mark/mark-42@2x.png) 2x,url(img/identity/mark/mark-42@3x.png) 3x)}
.mk.live.lift .stm::before{-webkit-mask-image:-webkit-image-set(url(img/identity/mark/mark-48@1x.png) 1x,url(img/identity/mark/mark-48@2x.png) 2x,url(img/identity/mark/mark-48@3x.png) 3x);mask-image:image-set(url(img/identity/mark/mark-48@1x.png) 1x,url(img/identity/mark/mark-48@2x.png) 2x,url(img/identity/mark/mark-48@3x.png) 3x)}

/* ---------- media variants, in cascade order ---------- */
@media(hover:none){.mk .lbl{opacity:.8}}
/* the scrim (≥601): tint, no frost, whole viewport, always one step under
   the floating drawer; open state never lists visibility */
#drawerScrim{display:none}
@media(min-width:601px){
  #drawerScrim{display:block;position:fixed;inset:0;z-index:calc(var(--z-drawer) - 1);background:rgba(var(--cream-rgb),.5);
    opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--t-ui),visibility 0s linear var(--t-ui)}
  #drawer.on + #drawerScrim{opacity:1;visibility:visible;pointer-events:auto;transition:opacity var(--t-ui)}
}
@media(max-width:600px){#hint::before{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--g-grain),var(--plate)}}
@media(min-width:981px){
  #cardBody .figure{max-height:36dvh}
  /* review r1 (B1 layout call): the photo takes the body's whole height —
     ≈ 381 px at 1440×900, the frame beside the thumbs, which stand as a
     column; Prev/Next fold into the strip (the lightbox keeps its arrows).
     --ph = the body's room: viewport − top bar − frame, heading, dock,
     paddings and the caption */
  #cardBody{--ph:clamp(200px,calc(100dvh - clamp(20px,4.5vh,44px) - var(--sp) - 410px),460px)}
  .figwrap:has(.figure.live){display:grid;grid-template-columns:min(calc(var(--ph) * .8),calc(100% - 54px)) 44px;
    column-gap:10px;justify-content:center;align-content:start}
  #cardBody .figure.live{grid-column:1;grid-row:1;max-height:none;width:100%}
  .figwrap:has(.figure.live) .figcap{grid-column:1/-1;grid-row:2}
  .figwrap:has(.figure.live) .galnav{display:none!important}   /* over paintGal's inline flex */
  /* the thumbs: a column as tall as the frame (contain:size gives the row
     to the photo), scrolling if it is shorter than six */
  .figwrap:has(.figure.live) .strip{grid-column:2;grid-row:1;align-self:stretch;contain:size;flex-direction:column;
    margin:0;padding:0 0 2px;scroll-snap-type:y proximity;scroll-padding-block:0}
  .figwrap:has(.figure.live) .strip button{flex:0 0 48px;width:44px}
  .figwrap:has(.figure.live)::after{display:none}
}
/* sticky only where the whole gallery (frame, caption, thumbs) fits the body
   (Chrome insets the sticky edge by the body's 24 px padding: that is the
   breath under the heading; a gallery taller than the body's room was
   pushed up flush under the hairline at the end of the scroll — review r1) */
@media(min-width:601px) and (min-height:800px){.figwrap{position:sticky;top:0}}
@media(max-width:980px){
  /* docks low and scrolls, Close always reachable */
  #histPanel{left:50%;transform:translate(-50%,0);top:auto;
    bottom:calc(var(--sp) + 84px + env(safe-area-inset-bottom,0px));width:min(520px,92vw);
    max-height:56vh;overflow-y:auto;overscroll-behavior:contain}
  /* v9 R: no readout or scale row under it any more — it stands on the zoom
     capsule's line */
  #creed{width:260px;top:auto;bottom:calc(84px + env(safe-area-inset-bottom,0px))}
  #creed h2{font-size:36px;margin-bottom:14px}
  #mark.small{--mk-s:.68}
  /* the camera lifts the coordinate above centre; the card top stays below it */
  #card{left:50%;right:auto;top:auto;bottom:calc(18px + env(safe-area-inset-bottom,0px));
    transform:translateX(-50%);width:min(740px,calc(100vw - 36px));max-height:72dvh}
  #cardBody{gap:20px}
  #hint{max-width:50vw}
  /* over the docked card: no frost on the photograph */
  body.hascard #menu{--g-tint:var(--paper);--g-frost:none}
  /* the card docks low: the right column is free above it — the compass
     hangs under the close pill */
  body.hascard #compass{right:calc(var(--sp) + env(safe-area-inset-right,0px));
    top:calc(clamp(20px,4.5vh,44px) + 56px + env(safe-area-inset-top,0px));bottom:auto}
}
@media(max-width:760px){
  .figure{aspect-ratio:4/3}
  #hint{bottom:auto;top:calc(clamp(20px,4.5vh,44px) + env(safe-area-inset-top,0px) + 56px)}
  /* it shares the menu's row: never peeking out from behind the open menu */
  body:has(#menu.on,#menu.leave) #hint{visibility:hidden}
}
/* fingers get room the cursor never needed — hit areas grow, nothing visible moves */
@media(pointer:coarse){
  .galnav button{min-height:44px;min-width:44px}
  /* the (i) stays a 24 px glyph; a fingertip finds it (review r1: 24×24) */
  .maplibregl-ctrl-attrib-button::after{content:"";position:absolute;inset:-10px}
  .ghost{position:relative}
  /* the marks keep their drawing size; the button beneath them grows to a fingertip */
  .mk{width:44px;height:44px}
  .mk .lbl{left:40px}
  .pinmk{width:44px;height:44px;display:grid;place-items:center}
  /* 16px also buys the field a fingertip's height (35px → 44px) */
  #drawer .fld input{padding:11px 0}
  .wlRow input{padding:10px 1px}
  /* fingertip room on the text links */
  #histPanel .hnav button{padding:12px 8px;margin:-8px -4px}
  #pinPanel .pa button{padding:11px 8px;margin:-7px -4px}
  /* invisible fingertip room. NO position here: they are already positioned */
  #lbX::after,#histX::after,#aboutX::after,#drawerClose::after,#pinPanel #pinX::after{
    content:"";position:absolute;inset:-14px -10px}
}
@media(max-width:600px){
  #mark.small{--mk-s:.71}
  #menuBtn{width:80px;gap:6px}
  #menuBtn .btnl{display:block;font-size:12px}
  /* v9-M: a sheet, gutter to gutter */
  #menu{width:auto;right:calc(var(--sp) + env(safe-area-inset-right,0px))}
  /* v9 R: the foot is free (no readout, no zoom, the credits fold to the (i)) */
  #creed{bottom:calc(64px + env(safe-area-inset-bottom,0px));width:calc(100vw - 2*var(--sp));padding-top:20px}
  /* the band: edge to edge, eased in above the words (no crease), opaque under them */
  #creed::before{content:"";position:absolute;z-index:-1;inset:-72px calc(-1*var(--sp)) -24px;pointer-events:none;background:var(--cream);
    --ramp:linear-gradient(#0000,#0000000e 13px,#00000033 26px,#00000065 39px,#0000009b 53px,#000000cd 66px,#000000f1 79px,#000 92px,#000 calc(100% - 24px),#0000);
    -webkit-mask:var(--ramp);mask:var(--ramp)}
  body.space #creed::before,#creed.on-night::before{background:var(--g-grain),#0C0F18}
  #creed h2{font-size:36px;line-height:1.08;margin-bottom:12px;max-width:250px}
  #creed #exploreNorway{margin-top:18px;min-height:46px;width:100%;justify-content:space-between}
  /* the foot belongs to the creed: the hint goes on top */
  #hint{width:max-content;max-width:calc(100% - 2*var(--sp));padding:7px 14px}
  #readout{bottom:calc(82px + env(safe-area-inset-bottom,0px))}
  /* phones pinch: no zoom capsule (v9 R, owner 2026-10-18) */
  #mapNav{display:none}
  /* the phone sheet: 24px corners, 8px in from the edges, 6px of glass around
     a concentric 18px mount */
  #card{width:calc(100vw - 16px);bottom:calc(8px + env(safe-area-inset-bottom,0px));max-height:73dvh;
    border-radius:var(--r-sheet);padding:6px}
  #cardMount{border-radius:18px}
  #placeHeading{padding:16px 16px 14px;gap:var(--s2)}
  #placeHeading h2{font-size:28px}
  #placeHeading .cd{font-size:11px;letter-spacing:0;margin-top:6px}
  .placePrice{font-size:15px;max-width:100px}
  /* photo first, in DOM order (reading order = visual order); the facts
     follow 40px below (.facts margin 20 + the 20px gap, v9 A fix r1); the
     dock stays pinned below */
  #cardBody{display:flex;flex-direction:column;padding:16px;scroll-padding:16px;align-items:stretch}
  .strip{min-width:0}
  /* the garment leads in portrait; studies stay landscape */
  #cardBody .figure{aspect-ratio:4/3;max-height:260px}
  #cardBody .figure:not(.study){aspect-ratio:4/5;max-height:44dvh}
  #cardBody .figure.live{max-height:none;width:min(100%,calc((73dvh - 290px) * .8))}
  /* the pin panel spans the width, above the zoom capsule and the scale bar */
  #pinPanel{left:var(--sp);right:var(--sp);width:auto;bottom:calc(138px + env(safe-area-inset-bottom,0px));
    max-height:calc(100dvh - 240px);overflow-y:auto;overscroll-behavior:contain}
  .facts{margin-top:20px}
  .facts .productIntro{font-size:20px}
  #purchaseDock{padding:12px 16px 14px;gap:var(--s3)}
  .sizes{gap:5px}
  .sizeLabel,.purchaseNote{font-size:11px;margin-bottom:6px;line-height:1.4}
  .purchaseAction .buy{font-size:12px;padding:10px 9px;min-height:44px}
  .purchaseAction{min-width:0}
  .galnav button{min-height:44px;padding:12px 8px}
  .figcap{min-height:0}
  /* the phone drawer is one thick, opaque sheet: no frost, no frame */
  #drawer{inset:0;width:100%;padding:0;border-radius:0}
  #drawer::before{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--paper);box-shadow:none}
  #drawer::after{display:none}
  #drawerBody{border-radius:0;box-shadow:none;padding-top:calc(var(--sp) + 48px + env(safe-area-inset-top,0px))}
  #drawerClose{top:calc(12px + env(safe-area-inset-top,0px));right:calc(12px + env(safe-area-inset-right,0px))}
  #about,#legal{padding-top:90px}
}
/* phones: pin mode sits under the top bar */
@media(max-width:480px){
  #pinMode{top:calc(clamp(20px,4.5vh,44px) + 56px + env(safe-area-inset-top,0px));bottom:auto;left:var(--sp);right:var(--sp);
    transform:none;max-width:none;justify-content:space-between}
}
@media(max-width:370px){
  #menuBtn{width:44px}
  #menuBtn .btnl{display:none}
  #mark{--wm-h:26px}
  #mark.small{--mk-s:.81}
  #purchaseDock{padding-left:12px;padding-right:12px;gap:8px}
  .sizes{gap:4px}
  .purchaseAction .buy{font-size:11px;padding:10px 5px}
}
/* a phone held sideways is still a phone: it pinches (v9 R) */
@media(pointer:coarse) and (max-height:580px){#mapNav{display:none}}
@media(max-height:580px) and (min-width:601px){
  #creed{top:28%;bottom:auto}
  #creed h2{font-size:28px}
  #creed #exploreNorway{margin-top:16px}
  /* review r1 (B1 layout call): centred, the card covered the place at every
     short landscape (844×390, 900×500, 1024/1180×560). It docks right under
     the close pill, one column, clear of the attribution row; the map band
     on the left keeps the place (placePad measures this card) */
  #card{top:calc(clamp(20px,4.5vh,44px) + 56px + env(safe-area-inset-top,0px));bottom:auto;left:auto;
    right:calc(var(--sp) + env(safe-area-inset-right,0px));transform:none;width:min(560px,58vw);
    max-height:calc(100dvh - clamp(20px,4.5vh,44px) - 56px - 34px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px))}
  #cardBody{grid-template-columns:minmax(0,1fr);gap:16px;padding:16px 20px}
  #cardBody .figure.live{width:min(100%,calc((100dvh - 240px) * .8))}
  #placeHeading{padding:12px 20px}
  #placeHeading h2{font-size:26px}
  #purchaseDock{padding:10px 20px}
  /* the card fills the short frame from 80px down: the compass joins the top
     row, beside the menu pill */
  body.hascard #compass{left:calc(var(--sp) + 112px + env(safe-area-inset-left,0px));right:auto;
    top:calc(clamp(20px,4.5vh,44px) + env(safe-area-inset-top,0px));bottom:auto}
}
/* hover answers only a real pointer — never a stuck state after a tap */
@media(hover:hover) and (pointer:fine){
  #menu button.mi:hover,#mapNav .icon:hover{background:var(--hov)}
  #mapNav .icon:hover{color:var(--ink)}
  #menuBtn:hover,#cardClose:hover,#compass:hover{--g-tint-c:var(--g-on)}
  :is(#menuBtn,#mapNav,#cardClose,#compass):hover{--glow:var(--g-glow)}
  #creed #exploreNorway:hover{background:#3B3F43}
  body.space #creed #exploreNorway:hover,#creed.on-night #exploreNorway:hover{background:var(--g-grain),rgba(66,73,92,.8)}
  #menu .mp:hover,#menu .mr:hover,#menu .mf:hover{background:var(--hov)}
  #menu .mv:not([aria-pressed="true"]):hover{background-color:var(--hov);color:var(--i70)}
  #menu .mf:hover{color:var(--ink)}
  #menu .mpVote:not([aria-pressed="true"]):hover .vi{box-shadow:inset 0 0 0 1px var(--ink);color:var(--ink)}
  #pinCancel:hover{color:var(--ink);background:var(--hov)}
  .vBtn:hover:not([disabled]):not(#voteBtn),.dSizes button:hover:not(.sel):not([disabled]){box-shadow:inset 0 0 0 1px var(--ink)}
  .strip button:hover{box-shadow:inset 0 0 0 1px var(--i45)}
  .strip button:hover img{opacity:1}
  .galnav button:hover,#lbX:hover,.lbArrow:hover,#aboutX:hover,#legalX:hover,#histX:hover,#histPanel .hnav button:hover,
  #pinPanel #pinX:hover,#cardClose:hover,#drawerClose:hover,.tlink:hover,.wlRow button:hover,.ghost:hover,#ckBack:hover,
  #pinPanel .pa button:hover,#pinPanel #pinVote:hover:not([disabled]){color:var(--ink);text-decoration-color:var(--ink)}
  .lbArrow:hover{background:var(--paper)}
  .ghost:hover{border-color:var(--ink)}
  #ckBack:hover{text-decoration-color:var(--ink)}
  .wlRow button:hover,.sizes button:hover:not(.sel):not([disabled]){border-color:var(--ink)}
  .buy:hover:not([disabled]):not(.sec),#voteBtn:hover:not([disabled]){background:#43474B;border-color:#43474B}
  .buy.sec:hover:not([disabled]){border-color:var(--ink)}
  .mk:hover .lbl{opacity:1;transition-duration:var(--dur-card)}
  .hm:hover .hl{opacity:1;transition-duration:var(--dur-card)}
  .hm:hover b{background:var(--ink);color:var(--cream)}
}
/* ---------- fallbacks: variable swaps — opaque paper (graphite in space);
   more contrast adds a 1px ink rim; forced colours go to the system */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :root,body.orbit{--g-tint:var(--paper);--g-tint-c:var(--paper);--g-on:var(--paper);--plate:var(--paper)}
  body.space,.on-night{--g-tint:#26282C;--g-tint-c:#26282C;--g-on:#26282C;--plate:#26282C}
}
@media(prefers-reduced-transparency:reduce),(prefers-contrast:more){
  :root,body.orbit{--g-tint:var(--paper);--g-tint-c:var(--paper);--g-on:var(--paper);--g-frost:none;--g-frost-c:none;--plate:var(--paper);--sheet:var(--paper)}
  body.space,.on-night{--g-tint:#26282C;--g-tint-c:#26282C;--g-on:#26282C;--plate:#26282C}
  #drawerScrim{background:rgba(var(--cream-rgb),.92)}
  html.fx-refract :is(#menuBtn,#mapNav,#cardClose,#compass)::before{backdrop-filter:none}
}
@media(prefers-contrast:more){
  :root{--g-rim:linear-gradient(var(--ink),var(--ink));--i45:rgba(46,49,52,.86);--i70:rgba(46,49,52,.92)}
  body.space,.on-night{--g-tint:#141826;--g-tint-c:#141826;--g-on:#141826;--plate:#141826;--g-rim:linear-gradient(var(--cream),var(--cream))}
}
@media(forced-colors:active){
  :root,body.orbit,body.space,.on-night{--g-tint:Canvas;--g-tint-c:Canvas;--g-on:Canvas;--g-grain:none;--grain:none;--paper:Canvas;--plate:Canvas;
    --g-frost:none;--g-frost-c:none;--g-rim:linear-gradient(CanvasText,CanvasText)}
  :focus-visible{outline-color:Highlight}
  .maplibregl-ctrl-attrib-button::before{forced-color-adjust:none;background:CanvasText}
  /* the masked wordmark and the masked circular mark: forced Canvas would
     erase them (R fix r1) */
  #mark::before,#aboutH::before,.stm::before{forced-color-adjust:none;background:CanvasText}
}
@media(prefers-reduced-motion:reduce){
  /* instant, but never on visibility (pseudos too): a frame of inherited
     "hidden" leaves a just-opened panel unfocusable (H1; v9 A fix r1 + B1) */
  *,*::before,*::after{transition-property:opacity,transform,color,background-color,border-color,box-shadow!important}
  /* MapLibre writes each marker's transform every frame: a .01ms transform
     transition paints it one frame behind the map (v9 A fix r2) */
  .maplibregl-marker{transition-property:opacity!important}
  /* the same for the compass needle, written from --bearing on every rotate */
  #compass svg{transition-property:none!important}
  *,*::before,*::after{animation:none!important;transition-duration:.01ms!important;transition-delay:0ms!important}
  #creed,#drawer{transition:none!important}
  /* C3: no slide — the drawer fades where it stands (app.js) */
  #drawer.leave:not(.on){transform:none;visibility:visible;pointer-events:none}
}

/* ===== intro (C1) ===== the first-visit stage (app.js INTRO); every
   visit opens on the night, never a cream frame before app.js runs */
body:not(.ready) #space{opacity:1}
#intro{position:fixed;inset:0;z-index:90;pointer-events:none}
#intro .c1-bg{position:absolute;inset:0;overflow:hidden;background:#090C15;
  background:url(img/fx/grain-space.png) 0 0/128px 128px,radial-gradient(farthest-corner at 50% 46% in oklab,rgb(14 18 32),rgb(5 7 13))}
#intro .c1-st{position:absolute;inset:0}
#intro .c1-mk,#intro .c1-nm,#intro .c1-ic{position:absolute;transform-origin:0 0;will-change:transform}
#intro .c1-h{position:absolute;opacity:0}
/* the CPU copies that fly; until the lift the reveal's vectors stand over
   them (owner 2026-10-20, motion-graphics reveal, app.js introVec) */
#intro .c1-c{position:absolute;display:block}
#intro.c1-v .c1-c{opacity:0}
#intro .c1-vm,#intro .c1-vs,#intro .c1-vn{position:absolute;inset:0}
#intro .c1-rf,#intro .c1-sf,#intro .c1-nf{fill:#fff}
#intro .c1-rf{opacity:0}
#intro .c1-tr,#intro .c1-hd{fill:none;stroke:#fff;stroke-linecap:round}
#intro .c1-tr{stroke-dasharray:1 1;stroke-dashoffset:1;opacity:.85}
#intro .c1-hd{stroke-dasharray:.03 1;stroke-dashoffset:.03;opacity:0}
#intro .c1-vs{clip-path:polygon(0 100%,0 100%,0 100%)}
#intro .c1-vn{-webkit-mask:linear-gradient(90deg,#000 50%,transparent 60%) 100% 0/220% 100% no-repeat;
  mask:linear-gradient(90deg,#000 50%,transparent 60%) 100% 0/220% 100% no-repeat}
#intro .c1-glow,#intro .c1-sw{position:absolute;border-radius:50%;opacity:0}
#intro .c1-glow{background:radial-gradient(closest-side,rgb(255 255 255/.16),rgb(214 226 255/.06) 55%,transparent)}
#intro .c1-sw{border:1px solid rgb(255 255 255/.7)}
#intro svg{position:relative;display:block;width:100%;height:100%;overflow:visible}
/* the live wordmark and Menu icon wait for the two that land; the hint for the lift */
html.c1-wm #mark,html.c1-mk #menuBtn .stm{visibility:hidden}
html.c1 #hint{color:transparent!important;visibility:hidden}
html.c1 #hint::before,html.c1 #hint::after{opacity:0}

/* v9-L provisional — B1 restyles. The quiet EN · NO toggle L1 puts in the
   menu footer's [data-slot="lang"] (inside #menu: no new glass host), and
   the Norwegian Terms' draft banner. */
/* v9-M: the current language in ink; NO ends on the right text edge */
#menu .mfoot .lang{display:flex;align-items:center;margin-left:auto;margin-right:-10px}
#menu .lang .mf{min-width:44px;padding:0 10px;color:var(--i45)}
#menu .lang .mf:last-child{text-align:right}
#menu .lang .mf[aria-pressed="true"]{color:var(--ink)}
#menu .lang .sep{font:400 12px/1 var(--sans);color:var(--i28)}
#legal .legalDraft strong{font-weight:400;color:var(--ink)}
/* SEO v9: no WebGL (app.js body.nomap) — no map, so no map controls; the
   prerendered card (place pages) or About (root) stands alone */
body.nomap #creed,body.nomap #mapNav,body.nomap #galnav,body.nomap #strip,body.nomap #hint{display:none}
body.nomap .figure:empty,body.nomap .figcap:empty{display:none}
/* SEO v9: a menu place row is a link (app.js placeRowHtml), dressed as the row */
#menu a.mpGo{color:inherit;text-decoration:none;cursor:pointer;touch-action:manipulation}
