/* emil.css — shared shell stylesheet.
   Typography and detail language studied from gwern.net (Emil-Wiki/tools/design-system.md):
   dotted-box navbar, ornament dividers instead of rules, dotted link underlines,
   centered page headers. */

@import url("fonts.css");

:root {
  --bg: #fff;
  --ink: #000;
  --link: #333;
  --link-hover: #888;
  --link-visited: #666;
  --rule: #888;
  --rule-soft: #ccc;
  --panel: #f8f8f8;
  --acc: #ddb05c;   /* the one accent — pastel gold (hardware, blossoms, cursor tip) */
  --invert: 0;
  --serif: "Source Serif 4", "Iowan Old Style", Charter, Georgia, "Times New Roman", serif;
  --measure: 935px;   /* gwern's body measure — one width for every page */

  /* ornaments, drawn in-house: a diamond star and a three-star asterism */
  --orn-star: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><path d="M 5,0 C 4,4 4,4 0,5 4,6 4,6 5,10 6,6 6,6 10,5 6,4 6,4 5,0 Z"/></svg>');
  --orn-asterism: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 12"><path d="M 5,1 C 4.3,3.8 4.3,3.8 1.5,4.5 4.3,5.2 4.3,5.2 5,8 5.7,5.2 5.7,5.2 8.5,4.5 5.7,3.8 5.7,3.8 5,1 Z"/><path d="M 13,4 C 12.3,6.8 12.3,6.8 9.5,7.5 12.3,8.2 12.3,8.2 13,11 13.7,8.2 13.7,8.2 16.5,7.5 13.7,6.8 13.7,6.8 13,4 Z"/><path d="M 21,1 C 20.3,3.8 20.3,3.8 17.5,4.5 20.3,5.2 20.3,5.2 21,8 21.7,5.2 21.7,5.2 24.5,4.5 21.7,3.8 21.7,3.8 21,1 Z"/></svg>');
}

/* There is no dark palette. Deleted 2026-08-22 at Emil's call: every scene
   declares its own light, and all of them are lit, so nothing could ever
   reach these values. `--invert` stays pinned at 0 for the artwork filters. */

* { box-sizing: border-box; }

/* the hand-drawn arrow from emilmeggle.me, as the site-wide cursor */
html {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 31 31"><path d="M2 3 L29 13 L15 16.5 L11 29 Z" fill="%23faf5ea" stroke="%23141414" stroke-width="1.4" stroke-linejoin="round"/><path d="M2 3 L29 13 L15 16.5 Z" fill="%23ffffff" stroke="%23141414" stroke-width="0.7"/></svg>') 2 3, auto;
}
a, button, summary, [role="button"] {
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 31 31"><path d="M2 3 L29 13 L15 16.5 L11 29 Z" fill="%23faf5ea" stroke="%23141414" stroke-width="1.4" stroke-linejoin="round"/><path d="M2 3 L29 13 L15 16.5 Z" fill="%23ddb05c" stroke="%23141414" stroke-width="0.7"/></svg>') 2 3, pointer;
}

html {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 20px;
}
/* The street exists only where a garage stands in it. A full page with no
   garage — a wiki article — is a sheet of paper in EVERY scene: a scene may
   skin the nav it carries, never the paper ("the room is always lit paper",
   design.md §9). Found 2026-08-27: city-bar's street under an article made
   the prose ~2:1 and the seven skip-ink shadows (still --bg white) turned
   every link into a white blob. */
html:has(.scene.garage) { background: var(--ground, var(--bg)); }
/* The world is its own layer: #world paints the street (one texture) behind
   the building; html keeps a static copy as the backdrop and for no-JS
   visitors. */
#world {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--ground, var(--bg));
}
@media (max-width: 649px) { html { font-size: 18px; } }

/* gwern's body texture: old-style figures in prose, lining figures in links,
   line-height stepping down with viewport width */
body { font-variant-numeric: oldstyle-nums; --line-height: 1.45; }
@media (min-width: 650px)  { body { --line-height: 1.50; } }
@media (min-width: 1000px) { body { --line-height: 1.55; } }
@media (min-width: 1200px) { body { --line-height: 1.60; } }

body { margin: 0; }

/* ---------------- the garage ------------------------------------------
   Built from design.md §4. The three rules, and everything else follows:

     air      clamp(24px, 14vmin, 168px)   -- even, on all four sides
     header   max(44px, 4.55% of width)    -- the nav, and the wall's top course
     opening  whatever is left

   14vmin reads against the screen's SHORT side, so the air always looks
   like the same amount of air and there is no breakpoint. The opening's
   shape therefore follows the screen; on a phone the garage simply goes
   phone-shaped, because a phone is 1:2.2 and nothing garage-shaped fits it.

   Nothing here measures a bitmap. The door is drawn. */

/* ============================================================================
   THE SCENE CONTRACT
   ----------------------------------------------------------------------------
   A garage has BONES and a SKIN. The bones never change; the skin is the scene.

   BONES - fixed for every scene, declared on .scene.garage further down:
     --air --scene-w --hdr --band
     and the structure itself: a wall, a header that IS the nav, an opening in
     the wall, a door over the opening. A scene may not move or remove these.

   SKIN - a scene sets exactly the tokens below and NOTHING else. No rule in the
   garage may carry a colour literal; if one does, that value is invisible to
   every future scene and the contract is a lie.

     world      --ground        the space the garage stands in. NOT --bg:
                                that is the room's paper, and a night street
                                and a lit interior are not the same surface.
                                Found missing while building city-bar.
                --floor         the DRIVEWAY the garage stands on: the whole
                                background of the ground band below the wall
                                (Emil's sketch: a one-point-perspective plane,
                                garage-wide at its horizon, viewport-wide at
                                the bottom edge). A whole value like --reveal,
                                because the ground IS light and material.
                                Optional; omit it and the garage floats on
                                the wall as before.
                --floor-blend   the per-layer blend list for --floor. Optional.
                --horizon       where the ground band's top edge sits, seen
                                from <html>: the same clamp as --air, restated
                                because --air is registered with initial 0px
                                and lives on .scene.garage, so --ground (used
                                on html) can never read it. A scene drawing a
                                WORLD into --ground anchors its horizon with
                                this. Optional; a scene without a world never
                                needs it, and no structural rule reads it.
                --wall-tex      the WALL's texture, and only the wall's.
                --wall-tex-size --grain is worn by the wall, the keys and the
                --wall-tex-blend  door together, so it can never carry a
                                pattern. These three can. All optional; a
                                scene that omits them gets --grain. S.10.
     material   --clad-h/-s/-l  the wall
                --key-h/-s/-l   the nav keys. Usually the same stone as the
                                wall and they default to it -- but brick wants
                                a concrete lintel over a brick wall, which one
                                material cannot say.
                --slab          the door
                --dark          the void behind the door
                --grain         the texture laid over everything
                --joint-ink     the gap between keys
     ink        --clad-ink      key labels
                --clad-ink-lk   locked key labels
                --clad-ink-on   the label on a sunken key - the one you are
                                standing on. Found by measuring contrast in
                                city-bar, where the old hard-coded black gave
                                1.95:1.
     light      --lip-hi/-lo    the key's bevel
                --face-hi/-lo   how hard the key's face catches light
                --reveal        the opening's edge, as a whole box-shadow
                --panel-light   the door's per-panel light, as a whole gradient
                --panel-light-size / -repeat  its AXIS. Optional; omit and the
                                light rakes down each panel. S.5.
                --cast          the garage's own shadow on the ground
     door       --scene-panels  how many panels the door is made of. Optional;
                                omit it and the count stays responsive (4, and
                                5 on a widescreen or a phone). NOT --panels --
                                that is set directly on the garage and a
                                scene's inherited value cannot beat it.
                --door-tag      the mark on the door, as a whole background
                --door-tag-size layer. `none` for a bare door. Optional.

   --reveal and --panel-light are whole values, not colours, on purpose: light
   is the thing a scene most owns, and a neon scene does not want the modern
   reveal in another colour - it wants the opening to EMIT rather than recede.

   Scenes are selected by html[data-scene] (theme.js, default "modern"), and a
   scene decides for itself whether it offers a day and a night.
   ============================================================================ */

:root {
  --joint: 2px;
  /* the grey ladder of secondary text, darkest to lightest */
  --meta-ink: #555;       /* page-metadata under a masthead */
  --faint-ink: #777;      /* figcaptions, provenance, placeholders, statuses */
  --soft-ink: #999;       /* dates, counters, doc metadata */
  /* blockquote nesting: each level one step lighter */
  --quote-rule: #ccc;
  --quote-rule-2: #c4c4c4;
  --quote-bg-2: #e6e6e6;
  --quote-rule-3: #b3b3b3;
  --quote-bg-3: #d8d8d8;
  /* drawn-object ink: the Postkasten's card borders, the expand glyph —
     the dark line of things drawn on paper, not the page's text ink */
  --draw-ink: #141414;
  --paper-card: #fdfdfc;  /* the Postkasten's paper objects */
  /* the ground band's height — the --air clamp restated on html, because a
     token substituting var(--air) up here sees --air's initial 0px (the
     measured trap of 2026-08-29). Every scene's way derives from it. */
  --horizon: clamp(24px, 14vmin, 168px);
}

/* ---- scene: MODERN - daylight on a clean sectional door -------------------- */
/* `:not([data-scene])` is not a second scene - it is modern before theme.js
   has run. The script is deferred, so without this the garage paints with no
   cladding at all for a frame. */
:root:not([data-scene]),
[data-scene="modern"],
[data-scene="atelier"],
[data-scene="basalt"] {
  /* the cladding marries the klinker (ONE thing, Emil 2026-08-29): hue
     walks from cool 212 to warm-neutral 40 so band, keys and wall share a
     temperature — the material stays clean metal, only the light agrees */
  --joint-ink: hsl(40 7% 30%);
  --clad-h: 40; --clad-s: 5%; --clad-l: 75.5%;
  --clad-ink-here: #17150f;  /* gold is 1.3:1 on this pale cladding */
  --clad-ink: #3f4448;
  --clad-ink-lk: #83888c;
  --clad-ink-on: #000;
  --lip-hi: rgba(255,255,255,.13);
  --lip-lo: rgba(0,0,0,.13);
  --face-hi: .028;
  --face-lo: .045;
  --slab: #d7dade;
  --dark: #14171a;
  /* THE WORLD (2026-08-29, Emil: "this is the garage and there is sky, nature
     etc in the background"). The building is freestanding: clear daylight sky,
     two barely-there clouds, and a distant treeline standing ON the horizon --
     the garage's foot line, var(--horizon) above the bottom of the page. Below
     that line the sky turns to meadow, which the drive band covers on any
     screen wide enough to have one (>=900px); between 650 and 899px the
     building simply stands on the meadow. The clouds live in the top 14% --
     the open sky above the roof is only --air tall, so anything lower is
     parked behind the building (measured: a cloud at 16% was). */
  --ground:
    linear-gradient(to bottom, rgba(255,255,255,.07) 0, rgba(255,255,255,0) 22%, rgba(20,23,26,0) 70%, rgba(20,23,26,.09) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='464' height='160'%3E%3Crect width='464' height='160' fill='%23b9b3aa'/%3E%3Crect x='1.5' y='1.5' width='229' height='37' fill='%23c9c4bb'/%3E%3Crect x='1.5' y='1.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='1.5' y='36.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='233.5' y='1.5' width='229' height='37' fill='%23d8d3ca'/%3E%3Crect x='233.5' y='1.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='233.5' y='36.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='-114.5' y='41.5' width='229' height='37' fill='%23d1ccc3'/%3E%3Crect x='-114.5' y='41.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='-114.5' y='76.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='117.5' y='41.5' width='229' height='37' fill='%23d8d3ca'/%3E%3Crect x='117.5' y='41.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='117.5' y='76.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='349.5' y='41.5' width='229' height='37' fill='%23cdc8bf'/%3E%3Crect x='349.5' y='41.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='349.5' y='76.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='1.5' y='81.5' width='229' height='37' fill='%23c9c4bb'/%3E%3Crect x='1.5' y='81.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='1.5' y='116.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='233.5' y='81.5' width='229' height='37' fill='%23d4cfc6'/%3E%3Crect x='233.5' y='81.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='233.5' y='116.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='-114.5' y='121.5' width='229' height='37' fill='%23d8d3ca'/%3E%3Crect x='-114.5' y='121.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='-114.5' y='156.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='117.5' y='121.5' width='229' height='37' fill='%23c9c4bb'/%3E%3Crect x='117.5' y='121.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='117.5' y='156.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Crect x='349.5' y='121.5' width='229' height='37' fill='%23d8d3ca'/%3E%3Crect x='349.5' y='121.5' width='229' height='1.5' fill='%23ffffff' opacity='.35'/%3E%3Crect x='349.5' y='156.5' width='229' height='2' fill='%23000000' opacity='.07'/%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.55' numOctaves='3' stitchTiles='stitch' seed='8'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.45 0 0 0 0 0.43 0 0 0 0 0.4 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='464' height='160' filter='url%28%23n%29'/%3E%3C/svg%3E") 0 0 / 464px 160px,
    #b9b3aa;
  /* The building against the sky. The first roof draft capped it with a
     9px anthracite fascia — Emil read it as a stray black bar over the nav
     (2026-08-29) and it went. What remains says "solid object in daylight"
     without adding a part: a 1px sunlit top edge (the roof plane catching
     the light from above), a hair of shade tucked under each side so the
     walls turn away from the sky, and the ground shadow. */
  --cast:
    0 -1px 0 0 rgba(255,255,255,.75),
    1px 0 0 0 rgba(20,23,26,.14),
    -1px 0 0 0 rgba(20,23,26,.14),
    0 26px 62px -34px rgba(20,23,26,.5),
    /* side relief only — the bottom inset left with the bottom band
       (2026-08-30): it had started shading the DOOR's foot */
    inset 14px 0 18px -14px rgba(20,23,26,.11),
    inset -14px 0 18px -14px rgba(20,23,26,.11);
  
  --reveal:
    inset 0 3px 0 0 rgba(6,8,10,.92),
    inset 3px 0 0 0 rgba(6,8,10,.80),
    inset -3px 0 0 0 rgba(6,8,10,.80),
    inset 0 -2px 0 0 rgba(6,8,10,.70),
    inset 0 16px 18px -12px rgba(6,8,10,.85),
    inset 14px 0 16px -12px rgba(6,8,10,.62),
    inset -14px 0 16px -12px rgba(6,8,10,.62),
    inset 0 -12px 14px -12px rgba(6,8,10,.50);
  --panel-light: linear-gradient(to bottom,
      rgba(255,255,255,.50) 0, rgba(255,255,255,.12) 1.6%,
      rgba(255,255,255,0) 14%, rgba(0,0,0,0) 86%, rgba(0,0,0,.34) 100%);
  /* one 160px turbulence tile, the only raster in the building, and it is a
     FILL over drawn geometry -- nothing takes a measurement from it.
     sRGB or linearRGB washes it out; stitchTiles or the tile seams; the
     alpha table forces grey noise rather than a patchy veil. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch' seed='11'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='0.42' intercept='0.29'/%3E%3CfeFuncG type='linear' slope='0.42' intercept='0.29'/%3E%3CfeFuncB type='linear' slope='0.42' intercept='0.29'/%3E%3CfeFuncA type='table' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- scene: BRICK - a green shutter in an old wall ------------------------
   From design/reference/garage-shutter-graffiti-brick.webp: red brick gone
   patchy with age, a cast concrete lintel across the top, and a dark green
   painted shutter in the hole. Daylight, weathered, warm.

   Two things this scene needed that the contract did not have:

   1. The wall has a PATTERN, not a colour. --grain carries it: the tile is
      greyscale on purpose, because it is blended `overlay` over --clad, so
      light bricks lighten and the mortar darkens and the colour stays the
      scene's. A brick-coloured tile would fight the token.
   2. The nav is NOT the wall here. It is the lintel - one cast concrete beam
      over the opening, which is exactly what the nav already is structurally.
      Hence --key-*, defaulting to the wall everywhere else. */
[data-scene="brick"] {
  /* dark brick swallows a black object; a pale daylight rim lifts it off the wall */
  --pk-filter: drop-shadow(0 0 5px rgba(255,246,232,.5)) drop-shadow(0 2px 3px rgba(0,0,0,.45));
  --pk-hi: #4c443c;
  --pk-paper: #6b645c;
  /* The brick is the WALL THE GARAGE IS SET INTO, not the garage. That is what
     the reference photo actually shows: the door is a hole in a brick wall,
     and the only thing framing it is cast concrete. So the brick rides
     --ground, and the garage's own band and lintel are concrete.
     It cannot ride --grain: that one token is worn by the wall, the nav keys
     AND the door, so a brick tile there bricks the door too. Tried it; the
     door came out as masonry. See tasks.md S.9. */
  /* The wall, layered the way a real one weathers. Top to bottom:
       damp and soot pooling high and in the corners, a pale bloom low where
       the pavement throws light back, then the brick itself, then the base
       colour under the mortar. The stain layers are sized to the VIEWPORT, not
       the tile, so they beat against the 320x240 course and the repeat stops
       reading as a stamp. The tile itself is anchored at (--horizon,
       --horizon) — the garage's top-left corner — so a course line lands on
       the lintel and a joint meets the building's left edge, with half-brick
       toothing on the offset courses: the wall is BUILT AROUND the garage,
       not painted behind it (Emil, 2026-08-30). */
  --ground:
    linear-gradient(118deg, rgba(255,234,196,.27), rgba(255,234,196,0) 48%, rgba(53,35,26,.18)),
    radial-gradient(ellipse at 15% 0%, rgba(72,49,32,.16), transparent 65%),
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22600%22%20height%3D%22240%22%3E%3Crect%20width%3D%22600%22%20height%3D%22240%22%20fill%3D%22%23b3a393%22%2F%3E%3Crect%20x%3D%22-118%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M-117%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M-117%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23986651%22%2F%3E%3Cpath%20d%3D%22M3%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M3%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22122%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M123%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M123%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22242%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M243%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M243%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22362%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M363%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M363%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22482%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M483%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M483%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22602%22%20y%3D%222%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M603%203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M603%2038h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22-58%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M-57%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M-57%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%2262%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M63%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M63%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22182%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M183%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M183%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22302%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M303%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M303%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22422%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a77561%22%2F%3E%3Cpath%20d%3D%22M423%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M423%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22542%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a77561%22%2F%3E%3Cpath%20d%3D%22M543%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M543%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22662%22%20y%3D%2242%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M663%2043h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M663%2078h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22-118%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23986651%22%2F%3E%3Cpath%20d%3D%22M-117%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M-117%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M3%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M3%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22122%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23986651%22%2F%3E%3Cpath%20d%3D%22M123%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M123%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22242%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M243%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M243%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22362%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M363%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M363%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22482%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M483%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M483%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22602%22%20y%3D%2282%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M603%2083h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M603%20118h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22-58%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M-57%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M-57%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%2262%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M63%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M63%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22182%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23986651%22%2F%3E%3Cpath%20d%3D%22M183%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M183%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22302%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M303%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M303%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22422%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M423%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M423%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22542%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a77561%22%2F%3E%3Cpath%20d%3D%22M543%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M543%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22662%22%20y%3D%22122%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M663%20123h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M663%20158h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22-118%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M-117%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M-117%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M3%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M3%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22122%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M123%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M123%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22242%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M243%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M243%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22362%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M363%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M363%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22482%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M483%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M483%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22602%22%20y%3D%22162%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a16d59%22%2F%3E%3Cpath%20d%3D%22M603%20163h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M603%20198h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22-58%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M-57%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M-57%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%2262%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23b0826c%22%2F%3E%3Cpath%20d%3D%22M63%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M63%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22182%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a77561%22%2F%3E%3Cpath%20d%3D%22M183%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M183%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22302%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M303%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M303%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22422%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a5725e%22%2F%3E%3Cpath%20d%3D%22M423%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M423%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22542%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23a77561%22%2F%3E%3Cpath%20d%3D%22M543%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M543%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Crect%20x%3D%22662%22%20y%3D%22202%22%20width%3D%22117%22%20height%3D%2237%22%20rx%3D%221.2%22%20fill%3D%22%23ae7b65%22%2F%3E%3Cpath%20d%3D%22M663%20203h115%22%20stroke%3D%22%23e5b89a%22%20opacity%3D%22.28%22%2F%3E%3Cpath%20d%3D%22M663%20238h115%22%20stroke%3D%22%23583c2f%22%20opacity%3D%22.28%22%2F%3E%3Cfilter%20id%3D%22n%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%22.65%22%20numOctaves%3D%223%22%20stitchTiles%3D%22stitch%22%2F%3E%3CfeColorMatrix%20type%3D%22saturate%22%20values%3D%220%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22600%22%20height%3D%22240%22%20filter%3D%22url%28%23n%29%22%20opacity%3D%22.12%22%2F%3E%3C%2Fsvg%3E") var(--horizon) var(--horizon) / 600px 240px,
    #a5725e;
  --clad-h: 36; --clad-s: 15%; --clad-l: 75%;
  --joint-ink: hsl(32 9% 38%);
  --clad-ink: #33302b;
  --clad-ink-lk: #615c53;   /* was #918a7e: 1.61:1 on light concrete */
  --clad-ink-on: #17150f;
  --clad-ink-here: #17150f;  /* gold is 1.09:1 on this concrete */
  --lip-hi: rgba(255,252,244,.34);
  --lip-lo: rgba(48,36,24,.24);
  --face-hi: .04;
  --face-lo: .07;
  /* Was #24382e — the green shutter. Emil, 2026-08-29: "no green door";
     brick keeps its wall and takes the standard pale sectional door,
     warmed a touch so it sits in the lane's light rather than modern's. */
  --slab: #e0d9cd;
  --dark: #0d100e;
  --cast: 0 26px 62px -30px rgba(30,18,12,.72);
  /* the way in brick: worn warm flags under the old wall */
  --way-base: #8f8478;
  --way-joint: rgba(43,31,22,.32);
  --way-lit: rgba(255,246,232,.15);
  --way-contact: rgba(20,12,8,.52);
  --way-shade: rgba(26,16,10,.22);
  --way-cast: rgba(26,16,10,.46);
  
  --reveal:
    inset 0 4px 0 0 rgba(14,12,10,.94),
    inset 3px 0 0 0 rgba(14,12,10,.82),
    inset -3px 0 0 0 rgba(14,12,10,.82),
    inset 0 -2px 0 0 rgba(14,12,10,.72),
    inset 0 22px 22px -12px rgba(14,12,10,.88),
    inset 15px 0 17px -12px rgba(14,12,10,.64),
    inset -15px 0 17px -12px rgba(14,12,10,.64),
    inset 0 -12px 14px -12px rgba(14,12,10,.52);
  --panel-light: linear-gradient(to bottom,
      rgba(255,255,255,.26) 0, rgba(255,255,255,.07) 2%,
      rgba(255,255,255,0) 15%, rgba(0,0,0,0) 82%, rgba(0,0,0,.42) 100%);
  /* every surface still needs the fine noise -- the door's background-image is
     a three-layer list including var(--grain), and one missing custom property
     invalidates the WHOLE declaration. Leave it out and the door renders with
     no background at all. Learned the hard way. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch' seed='11'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='0.42' intercept='0.29'/%3E%3CfeFuncG type='linear' slope='0.42' intercept='0.29'/%3E%3CfeFuncB type='linear' slope='0.42' intercept='0.29'/%3E%3CfeFuncA type='table' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Daylit material studies. Shared geometry and paper interior stay constant. */
[data-scene="atelier"] {
  --ground:
    radial-gradient(ellipse at 10% 0%, rgba(255,243,204,.8), transparent 66%),
    linear-gradient(115deg, rgba(97,70,37,0) 58%, rgba(97,70,37,.18) 100%), #d4c5a8;
  --clad-h: 31; --clad-s: 32%; --clad-l: 62%;
  --clad-ink: #302419; --clad-ink-lk: #483522;
  --clad-ink-on: #20180f; --clad-ink-here: #20180f;
  --joint-ink: #705033;
  --wall-tex: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22360%22%20height%3D%22540%22%20viewBox%3D%220%200%20360%20540%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23603b20%22%20stroke-width%3D%22.7%22%20opacity%3D%22.19%22%3E%3Cpath%20d%3D%22M0%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M7%200%20C-1%2090%2016%20140%207%20230%20S-2%20420%207%20540%22%2F%3E%3Cpath%20d%3D%22M14%200%20C6%2090%2023%20140%2014%20230%20S5%20420%2014%20540%22%2F%3E%3Cpath%20d%3D%22M21%200%20C13%2090%2030%20140%2021%20230%20S12%20420%2021%20540%22%2F%3E%3Cpath%20d%3D%22M28%200%20C20%2090%2037%20140%2028%20230%20S19%20420%2028%20540%22%2F%3E%3Cpath%20d%3D%22M35%200%20C27%2090%2044%20140%2035%20230%20S26%20420%2035%20540%22%2F%3E%3Cpath%20d%3D%22M42%200%20C34%2090%2051%20140%2042%20230%20S33%20420%2042%20540%22%2F%3E%3Cpath%20d%3D%22M49%200%20C41%2090%2058%20140%2049%20230%20S40%20420%2049%20540%22%2F%3E%3Cpath%20d%3D%22M56%200%20C48%2090%2065%20140%2056%20230%20S47%20420%2056%20540%22%2F%3E%3Cpath%20d%3D%22M63%200%20C55%2090%2072%20140%2063%20230%20S54%20420%2063%20540%22%2F%3E%3Cpath%20d%3D%22M70%200%20C62%2090%2079%20140%2070%20230%20S61%20420%2070%20540%22%2F%3E%3Cpath%20d%3D%22M77%200%20C69%2090%2086%20140%2077%20230%20S68%20420%2077%20540%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3Cpath%20d%3D%22M90%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M97%200%20C89%2090%20106%20140%2097%20230%20S88%20420%2097%20540%22%2F%3E%3Cpath%20d%3D%22M104%200%20C96%2090%20113%20140%20104%20230%20S95%20420%20104%20540%22%2F%3E%3Cpath%20d%3D%22M111%200%20C103%2090%20120%20140%20111%20230%20S102%20420%20111%20540%22%2F%3E%3Cpath%20d%3D%22M118%200%20C110%2090%20127%20140%20118%20230%20S109%20420%20118%20540%22%2F%3E%3Cpath%20d%3D%22M125%200%20C117%2090%20134%20140%20125%20230%20S116%20420%20125%20540%22%2F%3E%3Cpath%20d%3D%22M132%200%20C124%2090%20141%20140%20132%20230%20S123%20420%20132%20540%22%2F%3E%3Cpath%20d%3D%22M139%200%20C131%2090%20148%20140%20139%20230%20S130%20420%20139%20540%22%2F%3E%3Cpath%20d%3D%22M146%200%20C138%2090%20155%20140%20146%20230%20S137%20420%20146%20540%22%2F%3E%3Cpath%20d%3D%22M153%200%20C145%2090%20162%20140%20153%20230%20S144%20420%20153%20540%22%2F%3E%3Cpath%20d%3D%22M160%200%20C152%2090%20169%20140%20160%20230%20S151%20420%20160%20540%22%2F%3E%3Cpath%20d%3D%22M167%200%20C159%2090%20176%20140%20167%20230%20S158%20420%20167%20540%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3Cpath%20d%3D%22M180%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M187%200%20C179%2090%20196%20140%20187%20230%20S178%20420%20187%20540%22%2F%3E%3Cpath%20d%3D%22M194%200%20C186%2090%20203%20140%20194%20230%20S185%20420%20194%20540%22%2F%3E%3Cpath%20d%3D%22M201%200%20C193%2090%20210%20140%20201%20230%20S192%20420%20201%20540%22%2F%3E%3Cpath%20d%3D%22M208%200%20C200%2090%20217%20140%20208%20230%20S199%20420%20208%20540%22%2F%3E%3Cpath%20d%3D%22M215%200%20C207%2090%20224%20140%20215%20230%20S206%20420%20215%20540%22%2F%3E%3Cpath%20d%3D%22M222%200%20C214%2090%20231%20140%20222%20230%20S213%20420%20222%20540%22%2F%3E%3Cpath%20d%3D%22M229%200%20C221%2090%20238%20140%20229%20230%20S220%20420%20229%20540%22%2F%3E%3Cpath%20d%3D%22M236%200%20C228%2090%20245%20140%20236%20230%20S227%20420%20236%20540%22%2F%3E%3Cpath%20d%3D%22M243%200%20C235%2090%20252%20140%20243%20230%20S234%20420%20243%20540%22%2F%3E%3Cpath%20d%3D%22M250%200%20C242%2090%20259%20140%20250%20230%20S241%20420%20250%20540%22%2F%3E%3Cpath%20d%3D%22M257%200%20C249%2090%20266%20140%20257%20230%20S248%20420%20257%20540%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3Cpath%20d%3D%22M270%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M277%200%20C269%2090%20286%20140%20277%20230%20S268%20420%20277%20540%22%2F%3E%3Cpath%20d%3D%22M284%200%20C276%2090%20293%20140%20284%20230%20S275%20420%20284%20540%22%2F%3E%3Cpath%20d%3D%22M291%200%20C283%2090%20300%20140%20291%20230%20S282%20420%20291%20540%22%2F%3E%3Cpath%20d%3D%22M298%200%20C290%2090%20307%20140%20298%20230%20S289%20420%20298%20540%22%2F%3E%3Cpath%20d%3D%22M305%200%20C297%2090%20314%20140%20305%20230%20S296%20420%20305%20540%22%2F%3E%3Cpath%20d%3D%22M312%200%20C304%2090%20321%20140%20312%20230%20S303%20420%20312%20540%22%2F%3E%3Cpath%20d%3D%22M319%200%20C311%2090%20328%20140%20319%20230%20S310%20420%20319%20540%22%2F%3E%3Cpath%20d%3D%22M326%200%20C318%2090%20335%20140%20326%20230%20S317%20420%20326%20540%22%2F%3E%3Cpath%20d%3D%22M333%200%20C325%2090%20342%20140%20333%20230%20S324%20420%20333%20540%22%2F%3E%3Cpath%20d%3D%22M340%200%20C332%2090%20349%20140%20340%20230%20S331%20420%20340%20540%22%2F%3E%3Cpath%20d%3D%22M347%200%20C339%2090%20356%20140%20347%20230%20S338%20420%20347%20540%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%22%23fff0ce%22%20opacity%3D%22.2%22%3E%3Cpath%20d%3D%22M1%200h1v540h-1z%22%2F%3E%3Cpath%20d%3D%22M91%200h1v540h-1z%22%2F%3E%3Cpath%20d%3D%22M181%200h1v540h-1z%22%2F%3E%3Cpath%20d%3D%22M271%200h1v540h-1z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
  --wall-tex-size: 360px 540px; --wall-tex-blend: multiply;
  --slab: #c79961;
  --door-material-blend: normal, multiply, normal;
  --door-material:
    linear-gradient(110deg, rgba(255,237,193,.32), transparent 48%, rgba(69,39,17,.15)),
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22360%22%20height%3D%22540%22%20viewBox%3D%220%200%20360%20540%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23603b20%22%20stroke-width%3D%22.7%22%20opacity%3D%22.19%22%3E%3Cpath%20d%3D%22M0%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M7%200%20C-1%2090%2016%20140%207%20230%20S-2%20420%207%20540%22%2F%3E%3Cpath%20d%3D%22M14%200%20C6%2090%2023%20140%2014%20230%20S5%20420%2014%20540%22%2F%3E%3Cpath%20d%3D%22M21%200%20C13%2090%2030%20140%2021%20230%20S12%20420%2021%20540%22%2F%3E%3Cpath%20d%3D%22M28%200%20C20%2090%2037%20140%2028%20230%20S19%20420%2028%20540%22%2F%3E%3Cpath%20d%3D%22M35%200%20C27%2090%2044%20140%2035%20230%20S26%20420%2035%20540%22%2F%3E%3Cpath%20d%3D%22M42%200%20C34%2090%2051%20140%2042%20230%20S33%20420%2042%20540%22%2F%3E%3Cpath%20d%3D%22M49%200%20C41%2090%2058%20140%2049%20230%20S40%20420%2049%20540%22%2F%3E%3Cpath%20d%3D%22M56%200%20C48%2090%2065%20140%2056%20230%20S47%20420%2056%20540%22%2F%3E%3Cpath%20d%3D%22M63%200%20C55%2090%2072%20140%2063%20230%20S54%20420%2063%20540%22%2F%3E%3Cpath%20d%3D%22M70%200%20C62%2090%2079%20140%2070%20230%20S61%20420%2070%20540%22%2F%3E%3Cpath%20d%3D%22M77%200%20C69%2090%2086%20140%2077%20230%20S68%20420%2077%20540%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%2243%22%20cy%3D%22110%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3Cpath%20d%3D%22M90%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M97%200%20C89%2090%20106%20140%2097%20230%20S88%20420%2097%20540%22%2F%3E%3Cpath%20d%3D%22M104%200%20C96%2090%20113%20140%20104%20230%20S95%20420%20104%20540%22%2F%3E%3Cpath%20d%3D%22M111%200%20C103%2090%20120%20140%20111%20230%20S102%20420%20111%20540%22%2F%3E%3Cpath%20d%3D%22M118%200%20C110%2090%20127%20140%20118%20230%20S109%20420%20118%20540%22%2F%3E%3Cpath%20d%3D%22M125%200%20C117%2090%20134%20140%20125%20230%20S116%20420%20125%20540%22%2F%3E%3Cpath%20d%3D%22M132%200%20C124%2090%20141%20140%20132%20230%20S123%20420%20132%20540%22%2F%3E%3Cpath%20d%3D%22M139%200%20C131%2090%20148%20140%20139%20230%20S130%20420%20139%20540%22%2F%3E%3Cpath%20d%3D%22M146%200%20C138%2090%20155%20140%20146%20230%20S137%20420%20146%20540%22%2F%3E%3Cpath%20d%3D%22M153%200%20C145%2090%20162%20140%20153%20230%20S144%20420%20153%20540%22%2F%3E%3Cpath%20d%3D%22M160%200%20C152%2090%20169%20140%20160%20230%20S151%20420%20160%20540%22%2F%3E%3Cpath%20d%3D%22M167%200%20C159%2090%20176%20140%20167%20230%20S158%20420%20167%20540%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%22133%22%20cy%3D%22215%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3Cpath%20d%3D%22M180%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M187%200%20C179%2090%20196%20140%20187%20230%20S178%20420%20187%20540%22%2F%3E%3Cpath%20d%3D%22M194%200%20C186%2090%20203%20140%20194%20230%20S185%20420%20194%20540%22%2F%3E%3Cpath%20d%3D%22M201%200%20C193%2090%20210%20140%20201%20230%20S192%20420%20201%20540%22%2F%3E%3Cpath%20d%3D%22M208%200%20C200%2090%20217%20140%20208%20230%20S199%20420%20208%20540%22%2F%3E%3Cpath%20d%3D%22M215%200%20C207%2090%20224%20140%20215%20230%20S206%20420%20215%20540%22%2F%3E%3Cpath%20d%3D%22M222%200%20C214%2090%20231%20140%20222%20230%20S213%20420%20222%20540%22%2F%3E%3Cpath%20d%3D%22M229%200%20C221%2090%20238%20140%20229%20230%20S220%20420%20229%20540%22%2F%3E%3Cpath%20d%3D%22M236%200%20C228%2090%20245%20140%20236%20230%20S227%20420%20236%20540%22%2F%3E%3Cpath%20d%3D%22M243%200%20C235%2090%20252%20140%20243%20230%20S234%20420%20243%20540%22%2F%3E%3Cpath%20d%3D%22M250%200%20C242%2090%20259%20140%20250%20230%20S241%20420%20250%20540%22%2F%3E%3Cpath%20d%3D%22M257%200%20C249%2090%20266%20140%20257%20230%20S248%20420%20257%20540%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%22223%22%20cy%3D%22320%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3Cpath%20d%3D%22M270%200V540%22%20stroke-width%3D%222%22%20opacity%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M277%200%20C269%2090%20286%20140%20277%20230%20S268%20420%20277%20540%22%2F%3E%3Cpath%20d%3D%22M284%200%20C276%2090%20293%20140%20284%20230%20S275%20420%20284%20540%22%2F%3E%3Cpath%20d%3D%22M291%200%20C283%2090%20300%20140%20291%20230%20S282%20420%20291%20540%22%2F%3E%3Cpath%20d%3D%22M298%200%20C290%2090%20307%20140%20298%20230%20S289%20420%20298%20540%22%2F%3E%3Cpath%20d%3D%22M305%200%20C297%2090%20314%20140%20305%20230%20S296%20420%20305%20540%22%2F%3E%3Cpath%20d%3D%22M312%200%20C304%2090%20321%20140%20312%20230%20S303%20420%20312%20540%22%2F%3E%3Cpath%20d%3D%22M319%200%20C311%2090%20328%20140%20319%20230%20S310%20420%20319%20540%22%2F%3E%3Cpath%20d%3D%22M326%200%20C318%2090%20335%20140%20326%20230%20S317%20420%20326%20540%22%2F%3E%3Cpath%20d%3D%22M333%200%20C325%2090%20342%20140%20333%20230%20S324%20420%20333%20540%22%2F%3E%3Cpath%20d%3D%22M340%200%20C332%2090%20349%20140%20340%20230%20S331%20420%20340%20540%22%2F%3E%3Cpath%20d%3D%22M347%200%20C339%2090%20356%20140%20347%20230%20S338%20420%20347%20540%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%221.3333333333333333%22%20ry%3D%224%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%223.0%22%20ry%3D%229%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%225.333333333333333%22%20ry%3D%2216%22%2F%3E%3Cellipse%20cx%3D%22313%22%20cy%3D%22425%22%20rx%3D%228.333333333333334%22%20ry%3D%2225%22%2F%3E%3C%2Fg%3E%3Cg%20fill%3D%22%23fff0ce%22%20opacity%3D%22.2%22%3E%3Cpath%20d%3D%22M1%200h1v540h-1z%22%2F%3E%3Cpath%20d%3D%22M91%200h1v540h-1z%22%2F%3E%3Cpath%20d%3D%22M181%200h1v540h-1z%22%2F%3E%3Cpath%20d%3D%22M271%200h1v540h-1z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") 0 0 / 360px 540px,
    repeating-linear-gradient(90deg, rgba(73,42,19,.3) 0 1px, rgba(255,237,193,.3) 1px 2px, transparent 2px 90px);
  --panel-light: linear-gradient(to bottom, rgba(255,239,211,.3), transparent 2%, transparent 98.8%, rgba(53,31,13,.4) 100%);
  --lip-hi: rgba(255,230,190,.45); --lip-lo: rgba(71,42,20,.28);
  --cast: 0 -1px 0 rgba(255,235,198,.7), 18px 26px 45px -18px rgba(69,43,22,.42);
  --way-base: #b8a387; --way-joint: rgba(78,61,38,.19);
  --way-contact: rgba(65,47,26,.35); --way-cast: rgba(74,52,28,.27);
}
[data-scene="basalt"] {
  --ground:
    linear-gradient(125deg, rgba(245,249,246,.55), transparent 60%, rgba(42,53,50,.16)),
    repeating-linear-gradient(0deg, transparent 0 119px, rgba(73,83,76,.14) 119px 120px),
    repeating-linear-gradient(90deg, transparent 0 359px, rgba(73,83,76,.12) 359px 360px),
    #b8beb7;
  --clad-h: 100; --clad-s: 4%; --clad-l: 74%;
  --clad-ink: #343d38; --clad-ink-lk: #67716a;
  --clad-ink-on: #17231d; --clad-ink-here: #17231d;
  --joint-ink: #737d76; --slab: #555e5b;
  --door-material-blend: normal, normal;
  --door-material:
    linear-gradient(112deg, rgba(231,241,233,.24), transparent 42%, rgba(14,23,19,.2)),
    repeating-linear-gradient(0deg, rgba(224,235,227,.055) 0 1px, transparent 1px 3px);
  --panel-light: linear-gradient(to bottom, rgba(232,242,235,.5) 0, rgba(232,242,235,.05) 1%, transparent 8%, transparent 90%, rgba(13,22,17,.32) 100%);
  --lip-hi: rgba(244,250,242,.45); --lip-lo: rgba(39,50,41,.2);
  --cast: 0 -1px 0 rgba(246,253,241,.8), 0 26px 65px -28px rgba(24,37,29,.55);
  --way-base: #a3aaa3; --way-joint: rgba(35,48,39,.23);
  --way-contact: rgba(25,37,29,.4); --way-cast: rgba(27,42,32,.28);
}

::selection { background: var(--acc); color: var(--acc-ink, #000); }
:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

/* ---------------- the nav IS the wall's top course ---------------------
   Not a bar above the garage: in the reference the cladding runs straight
   across the head of the opening, so each room is one panel in it and the
   joints between rooms are the same shadow gaps as everywhere else.
   Eight cells -- mark, six rooms, settings -- as flex so the markup does
   not have to change. A grid takes a second row for free on a phone; a
   bar cannot, and that is the whole argument. */
.cassette {
  position: relative;
  display: flex;
  gap: var(--joint);
  background: var(--joint-ink);
  height: var(--hdr, 48px);
  padding: 0;
  z-index: 3;
}
nav#navbar.cassette { max-width: var(--measure); margin: 14px auto 0; }
.garage nav#navbar.cassette { max-width: none; margin: 0; flex: 0 0 auto; }

#navbar .logo,
#navbar .gear { flex: 1 0 0; position: static; transform: none; height: auto;
                display: flex; align-items: center; justify-content: center;
                margin: 0; padding: 0; opacity: 1; }
#navbar .links { flex: 7 0 0; position: static; transform: none; width: auto;
                 display: flex; gap: var(--joint); }
#navbar .links a { flex: 1 0 0; }

#navbar .logo, #navbar .gear, #navbar .links a {
  background-color: hsl(var(--key-h, var(--clad-h)) calc(var(--key-s, var(--clad-s)) + var(--j, 0) * 0.34%)
                        calc(var(--key-l, var(--clad-l)) + var(--j, 0) * 1%));
  background-image: var(--grain),
    linear-gradient(180deg, rgba(255,255,255,var(--face-hi)) 0, rgba(255,255,255,0) 20%,
                            rgba(0,0,0,0) 70%, rgba(0,0,0,var(--face-lo)) 100%);
  background-size: 160px 160px, 100% 100%;
  background-blend-mode: overlay, normal;
  box-shadow: inset 0 1px 0 var(--lip-hi), inset 0 -1px 0 var(--lip-lo);
  transition: background-color .13s ease, box-shadow .13s ease, color .13s ease;
}
/* real clad panels differ batch to batch; that step between neighbours is
   what a photograph shows and flat vector never does */
#navbar .logo            { --j: -1.9; }
#navbar .links a:nth-child(1) { --j:  1.2; }
#navbar .links a:nth-child(2) { --j: -0.5; }
#navbar .links a:nth-child(3) { --j:  0.7; }
#navbar .links a:nth-child(4) { --j: -1.3; }
#navbar .links a:nth-child(5) { --j:  1.7; }
#navbar .links a:nth-child(6) { --j: -0.2; }
#navbar .gear            { --j: -1.6; }

#navbar .logo .logo-img { height: 62%; width: auto; display: block; filter: none; }

#navbar .links a {
  position: relative;
  border: none;
  margin: 0;
  padding: 0.14em 0.3em;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  font-size: clamp(9px, 1.05vw, 14px);
  font-weight: 700;
  letter-spacing: 0.13em;
  color: var(--clad-ink);
  text-decoration: none;
  text-shadow: 0 1px 0 var(--lip-hi);
}
/* a room that is not open yet reads as unfinished, not forbidden --
   no padlock theatre */
#navbar .links a.locked { color: var(--clad-ink-lk); }
#navbar .links a.locked::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0.35em;
  width: 1.1em;
  height: 1px;
  transform: translateX(-50%);
  background: repeating-linear-gradient(to right, currentColor 0 3px, transparent 3px 6px);
  opacity: .6;
}
/* the press: a panel is a physical thing, so hover lifts it into the light
   and a press pushes it into the wall. The light law never changes -- the
   lit edge stays on top, it just moves. */
#navbar .links a:hover,
#navbar .logo:hover, #navbar .gear:hover {
  background-color: hsl(var(--key-h, var(--clad-h)) var(--key-s, var(--clad-s)) calc(var(--key-l, var(--clad-l)) + 4%));
  box-shadow: var(--key-hover-lip, inset 0 1px 0 rgba(255,255,255,.34)), inset 0 -1px 0 var(--lip-lo);
}
#navbar .links a:active,
#navbar .logo:active, #navbar .gear:active {
  background-color: hsl(var(--key-h, var(--clad-h)) var(--key-s, var(--clad-s)) calc(var(--key-l, var(--clad-l)) - 3.5%));
  box-shadow: var(--key-active-lip, inset 0 2px 3px rgba(0,0,0,.30)), inset 0 -1px 0 var(--lip-hi);
}
#navbar .links a.active {
  /* D.10, ruled by Emil 2026-08-30 ("theme sets accent"): the here-mark's
     ink is the SCENE's, like the sunken key's below — gold only where the
     cladding is dark enough to carry it (measured: 5.4:1 on city-bar,
     1.3:1 on modern, 1.09:1 on brick). */
  color: var(--clad-ink-here, var(--acc));
  background-color: hsl(var(--key-h, var(--clad-h)) var(--key-s, var(--clad-s)) calc(var(--key-l, var(--clad-l)) + 6%));
}
/* the gear is a machine part: it turns under the cursor, and keeps turning
   while it carries you to the settings page */
#navbar .gear { color: var(--clad-ink); border: none; line-height: 0; }
#navbar .gear[aria-current="page"] { color: var(--clad-ink-here, var(--acc)); }
#navbar .gear svg {
  height: 46%; width: auto; display: block;
  transition: transform 0.42s cubic-bezier(0.34, 0.72, 0.36, 1);
}
#navbar .gear:hover svg { transform: rotate(60deg); }

/* ---------------- the gear ROLLS (Emil's spec, 2026-08-29) --------------
   Click the gear and it detaches, rolls LEFT along the cassette wiping the
   keys as it passes, and hits the logo — which takes the hit like a comic
   panel: a crown of stars circles it for five seconds. The bar underneath
   is now one plain cladding panel with the settings ON it (the scene paint
   chips). Where the gear sat there is now an X that rolls everything back.
   All runtime-injected (theme.js); the shell markup stays untouched. */
#navbar .gear .g-x { display: none; }
#navbar.settings-mode .gear .g-gear { display: none; }
/* the slot stays EMPTY while the wheel is away (a gear cannot be in two
   places); the X arrives only with the crash, and leaves the moment the
   wheel starts rolling home */
#navbar.settings-mode.settled .gear .g-x { display: block; }
#navbar.settings-mode .gear:hover svg { transform: none; }
/* a key the wheel has reached is KNOCKED out, not faded: it drops, tips and
   shrinks under the rim in 0.2s. The per-key delay is computed in theme.js
   through the roll's own easing curve, so each key goes exactly when the
   wheel's rim touches it — never before, never after. */
#navbar .links a.wiped {
  opacity: 0;
  /* shoved the way the wheel travels: left and down, tipping backwards */
  transform: translate(-7px, 8px) rotate(-4deg) scale(0.9);
  pointer-events: none;
  /* the knock itself: quick and accelerating (this list applies on the way
     INTO .wiped; the way back out uses the key's normal press timing) */
  transition: transform 0.2s cubic-bezier(0.5, 0, 0.7, 0.4), opacity 0.2s cubic-bezier(0.5, 0, 0.7, 0.4);
}
/* once settled, the wiped keys leave the tab order too; visibility flips
   back the moment .settled lifts, so the close roll can fade them in */
#navbar.settings-mode.settled .links a { visibility: hidden; }
/* the X stays clickable above the plain panel (the phone grid's row spans
   the whole bar, so the panel would otherwise cover it) */
#navbar.settings-mode .gear { position: relative; z-index: 6; }
.gear-roller {
  position: absolute;
  z-index: 6;
  top: 50%;
  left: 0;
  color: var(--clad-ink);
  pointer-events: none;
  will-change: transform;
}
.gear-roller svg { width: 100%; height: 100%; display: block; }
/* One plain panel where the keys were: same material recipe as a key, so
   the "erased" bar reads as blank cladding, seams and all gone. */
.nav-settings {
  position: absolute;
  top: 7.5%;
  bottom: 7.5%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.24s ease;
  background-color: hsl(var(--key-h, var(--clad-h)) var(--key-s, var(--clad-s)) var(--key-l, var(--clad-l)));
  background-image: var(--grain),
    linear-gradient(180deg, rgba(255,255,255,var(--face-hi)) 0, rgba(255,255,255,0) 20%,
                            rgba(0,0,0,0) 70%, rgba(0,0,0,var(--face-lo)) 100%);
  background-size: 160px 160px, 100% 100%;
  background-blend-mode: overlay, normal;
  box-shadow: inset 0 1px 0 var(--lip-hi), inset 0 -1px 0 var(--lip-lo);
}
#navbar.settings-mode.settled .nav-settings { opacity: 1; pointer-events: auto; }
.nav-settings button {
  font: inherit;
  background: none;
  border: 0;
  padding: 2px;
  cursor: pointer;
  display: block;
}
.nav-settings button .chip { display: block; width: 46px; height: 30px; }
.nav-settings button .chip::before { width: 4px; height: 4px; top: 2px; }
.nav-settings button.on .chip { outline: 2px solid var(--acc); outline-offset: 1px; }
.nav-settings button:focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; }
/* phone grid: the plain panel spans the whole two-row bar, so the X sheds
   its own key face and floats on the panel instead of colliding with it */
@media (max-width: 649px) {
  #navbar.settings-mode .gear { background: none; box-shadow: none; }
}
/* the comic crown: five stars circling over the logo after the hit */
.crown {
  position: absolute;
  z-index: 7;
  pointer-events: none;
  width: 0;
  height: 0;
  animation: crown-spin 1.5s linear infinite;
}
.crown b {
  position: absolute;
  left: 0;
  top: 0;
  font-weight: normal;
}
.crown b i {
  position: absolute;
  left: -0.5em;
  font-style: normal;
  font-size: 16px;
  color: var(--acc);
  text-shadow: 0 0 3px var(--crown-glow, rgba(221, 176, 92, 0.55));
  animation: crown-twinkle 0.8s ease-in-out infinite alternate;
}
@keyframes crown-spin { to { transform: rotate(360deg); } }
@keyframes crown-twinkle { from { transform: scale(0.8); } to { transform: scale(1.15); } }
#navbar .logo-img { transform-origin: 50% 80%; }
#navbar .logo.hit .logo-img { animation: logo-jolt 0.55s cubic-bezier(0.3, 0.7, 0.4, 1); }
@keyframes logo-jolt {
  0% { transform: none; }
  18% { transform: translateX(5px) rotate(9deg) scale(0.88, 1.09); }
  45% { transform: translateX(-3px) rotate(-6deg) scale(1.07, 0.92); }
  72% { transform: translateX(1px) rotate(2.5deg) scale(0.97, 1.02); }
  100% { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .gear-roller, .crown, .crown b i { animation: none; transition: none; }
  #navbar .logo.hit .logo-img { animation: none; }
}
#navbar .gear:active svg,
#navbar .gear.turning svg { animation: gear-turn 1.1s linear infinite; }
@keyframes gear-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  #navbar .gear svg { transition: none; }
  #navbar .gear:active svg, #navbar .gear.turning svg { animation: none; }
}

/* ---------------- the wall, with a hole in it -------------------------- */
/* --air is registered so full screen can set it to 0 and every measurement
   in the garage follows (the zoom that once animated it is gone, 2026-09-02;
   full screen is the browser's own, see #expand). */
@property --air {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

.scene.garage {
  /* One air, at rest, always. The garage does not resize when you open it —
     tried 2026-08-22 (the "threshold"), reverted the same day: it spent the
     generous air Emil chose exactly when the site is in use, moved the nav
     under the cursor between clicks, and buildings do not resize. Reading room
     is `#expand`'s job instead. See design.md §7b. */
  --air: clamp(24px, 14vmin, 168px);
  --scene-w: calc(100vw - 2 * var(--air));
  --hdr: max(44px, calc(var(--scene-w) * 0.0455));
  --band: 22px;
  /* A scene may name a panel count; if it says nothing the door stays
     responsive -- 4 here, 5 on a widescreen and 5 on a phone, so it never
     turns back into a rollo. It has to be indirected like this because a
     scene sets tokens on <html> and they INHERIT, while this rule sets
     --panels DIRECTLY on the garage: a direct value beats an inherited one,
     so `[data-scene=x] { --panels: 6 }` did nothing at all. Verified.
     A scene that names a count owns it at every size -- same rule as its
     light. X.2, the door axis. */
  --panels: var(--scene-panels, 4);

  width: var(--scene-w);
  max-width: none;   /* .scene caps every other scene at 1100px; the garage is the page */
  height: calc(100dvh - 2 * var(--air));
  margin: 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  isolation: isolate;
  /* No --air transition any more (2026-08-27): animating it relayouted the
     whole garage every frame and stuttered. The zoom now moves by FLIP in
     theme.js — one layout jump, then a compositor transform. */
  background-color: hsl(var(--clad-h) var(--clad-s) var(--clad-l));
  /* THE WALL'S OWN SKIN. Not --grain: that token is worn by the wall, the nav
     keys AND the door at once, so a scene that put a pattern in it bricked the
     door too (S.9, tried and reverted). --wall-tex lands here and nowhere else,
     so a scene can give the wall stucco, corrugated steel or tile and leave the
     keys and the door alone.
     Written with a fallback, deliberately: --grain is MANDATORY (one missing
     custom property invalidates the whole declaration and the door renders
     bare), and this token must never inherit that trap. A scene that says
     nothing gets the grain it always had. Same shape as --ground above. */
  background-image: var(--wall-tex, var(--grain));
  background-size: var(--wall-tex-size, 160px 160px);
  background-blend-mode: var(--wall-tex-blend, overlay);
  box-shadow: var(--cast);
}

/* the night shadow rides --cast in the scene block now, not a rule of its own */
body.center { min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; }
body.center .scene.garage { margin: 0 auto; }

/* ---------------- the driveway ----------------------------------------
   The ground the garage stands on (Emil's own sketch): a one-point-
   perspective plane. At the horizon — the garage's foot line — it is exactly
   as wide as the garage; at the viewport's bottom edge it is the full
   viewport. So the drive's edges are straight lines from the garage's two
   bottom corners to the viewport's two bottom corners, and the leftover
   bottom triangles are the same ground receding sideways (the verge).

   ONE fact makes this drawable without a transform: the edge line drops
   var(--air) vertically while moving var(--air) horizontally, so it is 45deg
   in screen space at EVERY viewport. Extend both edges up and they meet at
   the vanishing point, (50vw, 50vw - air) above the horizon. A conic-gradient
   anchored THERE therefore draws correct one-point perspective for free:
   any longitudinal joint on the ground at fraction f of the drive's
   half-width is the ray at atan(f) from straight down — a fixed angle, every
   screen. Scenes place their joints/streaks at those angles inside --floor.

   The band is a ::after: below the garage's box, full viewport width, --air
   tall, so its top edge IS the garage's bottom edge and its bottom edge IS
   the viewport's. Wherever the air collapses — the phone default, full screen,
   fullscreen — height goes to 0 and the floor simply is not there, which is
   exactly the old look. ::before is taken (city-bar's neon sign). The
   garage's --cast paints UNDER this band (a pseudo-child always beats the
   root's box-shadow), so each scene bakes its contact shadow/glow into
   --floor's top layer instead. */
@media (min-width: 900px) {
  .scene.garage::after {
    content: "";
    position: absolute;
    top: 100%;
    left: calc(-1 * var(--air));
    width: 100vw;
    height: var(--air);
    pointer-events: none;
    /* THE WAY — one format, defined ONCE (2026-08-29): contact line and
       building shade seat the wall on the ground; two parallel courses,
       spacing compressing upward; two 45deg seams from the garage's
       corners to the viewport's. A scene supplies only COLOURS (--way-*),
       never lines: the format is the law, the material is the scene.
       --way-cast doubles as the light a scene throws on its own ground —
       city-bar's warm glare uses the same layer modern's shade does. */
    background:
      linear-gradient(to bottom, var(--way-contact, rgba(10,12,14,.38)) 0 2px, var(--way-shade, rgba(20,23,26,.16)) 2px, rgba(0,0,0,0) 24px),
      radial-gradient(70% 170% at 50% -10%, var(--way-cast, rgba(20,23,26,.38)) 0, rgba(0,0,0,0) 70%) 50% 0 / calc(100% - 2 * var(--horizon)) 100% no-repeat,
      var(--way-extra, linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0))),
      var(--grain) 0 0 / 160px 160px,
      conic-gradient(from 90deg at 50% calc(var(--horizon) - 50vw),
        rgba(0,0,0,0) 0deg 44.86deg,
        var(--way-joint, rgba(20,23,26,.20)) 44.86deg 45.14deg,
        var(--way-lit, rgba(255,255,255,.22)) 45.14deg 45.32deg,
        rgba(0,0,0,0) 45.32deg 134.68deg,
        var(--way-lit, rgba(255,255,255,.22)) 134.68deg 134.86deg,
        var(--way-joint, rgba(20,23,26,.20)) 134.86deg 135.14deg,
        rgba(0,0,0,0) 135.14deg 180deg),
      linear-gradient(to bottom,
        rgba(0,0,0,0) 0 30%,
        var(--way-joint, rgba(20,23,26,.18)) 30% calc(30% + 1.5px),
        var(--way-lit, rgba(255,255,255,.22)) calc(30% + 1.5px) calc(30% + 2.5px),
        rgba(0,0,0,0) calc(30% + 2.5px) 63%,
        var(--way-joint, rgba(20,23,26,.18)) 63% calc(63% + 1.5px),
        var(--way-lit, rgba(255,255,255,.22)) calc(63% + 1.5px) calc(63% + 2.5px),
        rgba(0,0,0,0) calc(63% + 2.5px) 100%),
      var(--way-base, #b3afa8);
    background-blend-mode: normal, normal, normal, overlay, normal, normal, normal;
  }
}

/* the opening, recessed behind the wall plane. The band round it is the
   SAME cladding -- a mid-grey ring reads as a picture frame, and no garage
   has one. The only dark thing is the reveal, which is the wall's own
   thickness seen head on. */
.garage .well {
  position: relative;
  flex: 1 1 auto;
  /* no bottom band (Emil, 2026-08-30): a real door meets the ground — the
     opening runs to the building's base and the door lands on the way */
  margin: 0 var(--band) 0;
  overflow: hidden;
  background: var(--dark);
}
.garage .well .frame {
  position: absolute;
  inset: 0;
  border: 0;
  aspect-ratio: auto;
}
.garage .well::after {
  content: "";
  position: absolute; inset: 0; z-index: 6; pointer-events: none;
  box-shadow: var(--reveal);
}

/* ---------------- the door --------------------------------------------
   Four wide panels, stored as a panel HEIGHT rather than a count, so it
   becomes five on a widescreen and five on a phone without ever turning
   back into a rollo. The seam is a bevel: each panel lit along its top
   edge and falling off at the bottom -- which commits the page to light
   from above, and everything else drawn agrees with it.
   It opens as ONE SHEET. Head on, a real sectional door does; the fold
   happens behind the header, out of sight. */
#curtain {
  position: absolute;
  inset: 0;
  z-index: 2;
  margin: 0; padding: 0; border: none;
  /* The tag is Emil's mark, and it is the third thing he named on the door
     after the panels and the seam -- so it is a token, not a literal. A scene
     that wants a bare door sets `--door-tag: none`. Fallback carries the
     current art, so a scene that says nothing is unchanged. X.2. */
  background:
    var(--door-tag, url("tag-wordmark.webp")) center / var(--door-tag-size, 86% auto) no-repeat,
    var(--door-material, linear-gradient(transparent, transparent)),
    var(--grain) 0 0 / 160px 160px,
    linear-gradient(var(--slab), var(--slab));
  background-blend-mode: normal, var(--door-material-blend, normal), overlay, normal;
  transform: translateY(0);
  /* GRAVITY (Emil, 2026-08-30): the state being ENTERED owns the timing.
     Base = closing: the sheet accelerates down and stops hard, 0.42s.
     .up below = opening: a strong pull, fast off the floor, easing out. */
  transition: transform 0.42s cubic-bezier(0.55, 0, 0.95, 0.7);
  /* NO standing will-change here: a permanently promoted layer re-samples
     the graffiti bitmap and it shipped soft (Emil caught it, 2026-08-29).
     theme.js promotes the door only for the moments it actually moves. */
}
#curtain.up { transition: transform 0.5s cubic-bezier(0.16, 0.9, 0.28, 1); }

/* The padlock (2026-08-27): a locked room's door shows it cannot be opened.
   An object over the door, not part of it — theme.js shows it only while a
   LOCKED room's door is down, and a pull on the door rattles it. Brass body
   rides --acc (hardware is what the accent is FOR); pointer-events pass
   through, so the click still lands on the door and gets refused there. */
#doorlock {
  position: absolute;
  left: 50%;
  bottom: calc(var(--band, 22px) + 2%);
  width: clamp(40px, 6.5%, 64px);
  transform: translateX(-50%);
  z-index: 3;
  pointer-events: none;
  display: none;
  filter: var(--lock-cast, drop-shadow(0 3px 4px rgba(0,0,0,.35)));
}
#doorlock.on { display: block; pointer-events: auto; cursor: pointer; }
/* The word (Emil, 2026-09-02): a small plate above the padlock where the
   visitor says it. Paper and ink, nothing brass -- the lock is the brass. */
.lock-word {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--band, 22px) + 2% + clamp(48px, 8%, 80px));
  z-index: 3; margin: 0;
}
.lock-word input {
  width: 9.5em; padding: 0.35em 0.6em; text-align: center;
  font: italic 0.85rem/1.3 "Source Serif 4", Georgia, serif;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--clad-ink, #333); border-radius: 3px; outline: none;
  box-shadow: 0 2px 6px var(--plate-cast, rgba(0, 0, 0, 0.18));
}
.lock-word input:focus { border-color: var(--ink); }
#doorlock svg { display: block; width: 100%; height: auto; transform-origin: 50% 18%; }
#doorlock.rattle svg { animation: lock-rattle 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes lock-rattle {
  0%, 100% { transform: rotate(0); }
  20% { transform: rotate(-9deg); }
  45% { transform: rotate(7deg); }
  70% { transform: rotate(-4deg); }
  85% { transform: rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) { #doorlock.rattle svg { animation: none; } }

/* THE HEAVE (Emil, 2026-08-30): a pull on the landing's door lifts it about
   a centimetre — a real strain, decelerating — then gravity wins and the
   sheet drops back, lands hard, bounces two pixels and sits. 1cm is written
   as 1cm because that is the brief. Per-segment easings live in the
   keyframes: up strains, the fall accelerates, the bounce dies. */
#curtain.heave { animation: door-heave 0.62s both; }
@keyframes door-heave {
  0%   { transform: translateY(0);    animation-timing-function: cubic-bezier(0.3, 0.7, 0.5, 1); }
  38%  { transform: translateY(-1cm); animation-timing-function: linear; }   /* the stall: same value to 50%, so this segment holds */
  50%  { transform: translateY(-1cm); animation-timing-function: cubic-bezier(0.5, 0, 1, 0.5); }
  70%  { transform: translateY(0);    animation-timing-function: cubic-bezier(0, 0.6, 0.4, 1); }
  80%  { transform: translateY(-2px); animation-timing-function: cubic-bezier(0.5, 0, 1, 1); }
  90%  { transform: translateY(0); }
  100% { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) { #curtain.heave { animation: none; } }
/* THE POINT, measured off a photograph rather than guessed: the paint is
   opaque coverage and the panel's own light is composited ABOVE it. That
   is what lets the bevel and the seams read THROUGH the tag. */
#curtain::after {
  content: "";
  position: absolute; inset: 0;
  mix-blend-mode: overlay;
  background-image: var(--panel-light);
  /* The AXIS is a scene's to choose, not just the ramp. Until 2026-08-23 the
     size and repeat were hard-coded here, so --panel-light could only ever
     rake DOWN a panel -- city-bar wanted the door lit from the side of the
     street and could not have it (S.5). A scene lighting across the whole
     door sets --panel-light-size: 100% 100% and --panel-light-repeat: no-repeat
     and gives its gradient a `to right`; the per-panel seams then come from
     its own gradient, which is the point of the token being a whole value.
     Both optional -- omit them and the door rakes per panel as it always has. */
  background-size: var(--panel-light-size, 100% calc(100% / var(--panels)));
  background-repeat: var(--panel-light-repeat, repeat-y);
}
/* The door goes fully away, and that is the correct head-on view — not a
   concession. A sectional door does lie flat overhead when it is open, but from
   eye level, straight on, that slab is hidden BEHIND the lintel. You only see it
   by looking up. This garage has a lintel: the nav, 54px of the same cladding,
   sitting directly above the opening. So the door tucks up behind the nav and
   the opening is clean.
   Tried the other way on 2026-08-22 — one foreshortened panel left hanging under
   the lintel, with its underside shaded and a lit leading edge. It read well and
   it was thrown away, because it cost 4.4-5.5% of the opening at EVERY screen
   size (the depth is a fraction of a panel, and a panel is a fraction of the
   opening, so growing the garage grows the slab with it). The whole open state
   is a fight for reading height; nothing decorative gets to take 5% of it.
   Do not re-add it without a viewpoint that looks up. */
#curtain.up {
  transform: translateY(-100%);
  transition: transform 1.05s cubic-bezier(0.6, 0, 0.2, 1);
}
#curtain.no-anim { transition: none !important; }
@media (prefers-reduced-motion: reduce) { #curtain { transition: none; } }

@media (min-width: 1600px) { .scene.garage { --panels: var(--scene-panels, 5); } }

/* ---------------- the phone -------------------------------------------
   Six room keys plus the gear do not fit across 280px at any font size. A
   grid takes a second row for free: four cells, two rows, ~90px, which is
   12% of the tall phone garage. The mark drops out -- the garage is the
   mark. */
@media (max-width: 649px) {
  /* The phone expands by DEFAULT (Emil, 2026-08-27): a phone has ~55px of
     air and nothing garage-shaped fits a 1:2.2 screen, so the air buys
     nothing there — the garage IS the screen. No wall, just the band, the
     nav and the door. Desktop air is untouched; #expand still offers the
     real Fullscreen API on top. */
  .scene.garage { --air: 0px; --band: 10px; --panels: var(--scene-panels, 5); }
  .garage nav#navbar.cassette {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: max(44px, 5.6vh);
    height: auto;
  }
  #navbar .logo { display: none; }
  #navbar .links { display: contents; }
  /* padding for these keys is set further down, after the nav rules that beat it */
  #navbar .links a { font-size: 11px; letter-spacing: .06em; }
  #navbar .gear svg { height: 40%; }
  /* Six rooms + the gear are seven keys in an eight-cell grid (Agency left
     the wall 2026-08-27). The gear spans the spare cell — a wall has no
     missing panel. */
  #navbar .gear { grid-column: span 2; }
}

header.masthead { margin: 2.2em 0 0; text-align: center; }
header.masthead h1 {
  margin: 0;
  font-size: 2.5rem;
  font-weight: 600;
  font-variant: small-caps tabular-nums;
  letter-spacing: -1px;
  line-height: 1.15;
  text-wrap: balance;
  border: none;
}
header.masthead .page-metadata {
  display: flex;
  flex-flow: wrap;
  justify-content: center;
  margin: 0.9em 0 0;
  font-size: 0.8rem;
  color: var(--meta-ink);
}
header.masthead .page-metadata span { white-space: nowrap; }
header.masthead .page-metadata span:not(:last-child)::after {
  content: "•";
  margin: 0 0.8em;
  opacity: 0.25;
}

/* ---------------- article ---------------- */

main {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 20px 40px;
}

p {
  font-size: 0.95rem;
  line-height: var(--line-height);
  text-align: justify;
  hyphens: auto;
  margin: 0 0 1em;
}

/* gwern's underline: a solid 1px hairline drawn as a repeating gradient at
   calc(100% - 0.1em), with offset text-shadows in the page background color
   punching skip-ink gaps around glyphs and descenders */
main a {
  color: var(--link);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 1px 1px;
  background-repeat: repeat-x;
  background-position: 0% calc(100% - 0.1em);
  font-variant-numeric: lining-nums;
  text-shadow:
       0      0.05em var(--bg),
       0.05em 0.05em var(--bg),
      -0.05em 0.05em var(--bg),
       0.17em 0.05em var(--bg),
      -0.17em 0.05em var(--bg),
       0.17em 0      var(--bg),
      -0.17em 0      var(--bg);
}
main a:hover { color: var(--link-hover); }
main a:visited { color: var(--link-visited); }
main a:visited:hover { color: var(--link-hover); }

h1 {
  font-size: 2rem;
  font-weight: 600;
  font-variant: small-caps tabular-nums;
  letter-spacing: -0.75px;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 4px;
  margin: 0 0 0.6em;
}

h2 {
  font-size: 1.2rem;
  font-weight: 600;
  font-variant: small-caps;
  border-bottom: 1px dotted var(--rule);
  padding-bottom: 2px;
  margin: 1.7em 0 0.5em;
}

/* ---------------- ornament dividers — hr is an ornament, not a line ---------------- */

hr {
  border: 0;
  display: flex;
  margin: 2.4em 0;
  height: 14px;
}
hr::after {
  content: "";
  margin: auto;
  width: 44px;
  height: 12px;
  background-image: var(--orn-asterism);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  opacity: 0.85;
  filter: invert(var(--invert));
}
hr.star::after {
  width: 14px;
  background-image: var(--orn-star);
}

/* ---------------- embedded scenes (Me / Sports) ---------------- */

.scene {
  max-width: 1100px;
  margin: 40px auto 60px;
  padding: 0 20px;
}
/* the plate: 16:9 behind the same dotted rule the nav boxes wear.
   While the embed loads, a quiet asterism curtain holds the space. */
.scene .frame {
  aspect-ratio: 16 / 9;
  border: 1px solid var(--ink);
  background: var(--bg);
  position: relative;
}
.scene .frame::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--orn-asterism) center / 44px no-repeat;
  opacity: 0.3;
  filter: invert(var(--invert));
}
.scene .frame iframe { position: relative; }

.scene .frame iframe {
  width: 100%; height: 100%; border: 0; display: block;
}
.scene figcaption {
  margin-top: 16px;
  font-size: 0.7rem;
  color: var(--faint-ink);
  text-align: center;
  font-variant: small-caps;
  letter-spacing: 0.05em;
}

/* ---------------- article content (exported wiki pages) ---------------- */

/* The way back from an article to the wiki index: one small word, top-left
   of the paper (Emil, 2026-09-01). The WIKI key does the same; this is for
   the reader whose eyes are on the page, not the cassette. */
.dropcap-first { position: relative; }
.dropcap-first .crumb {
  position: absolute; top: 0.9em; left: 1.2em;
  font-size: 0.7rem; font-variant: small-caps; letter-spacing: 0.06em;
  color: var(--meta-ink); background-image: none; text-shadow: none;
}
.dropcap-first .crumb:hover { color: var(--ink); }

/* A page's own drawing (Emil-Wiki `image: x.svg`, inlined by the exporter).
   Ink in currentColor on the paper, so it re-lights per scene without an
   invert(). Phone block sits AFTER the base rule — source order decides.
   A bitmap (Emil's own poster) is the file itself: keep aspect, no crop. */
.dropcap-first .wiki-art { float: right; width: 42%; max-width: 238px; margin: 0.2em 0 0.8em 1.6em; }
.dropcap-first .wiki-art svg { width: 100%; height: auto; display: block; color: var(--ink); }
.dropcap-first .wiki-art img { width: 100%; height: auto; display: block; }
.dropcap-first .wiki-art:has(> img) {
  float: none;
  width: min(100%, 30rem);
  max-width: 100%;
  margin: 0.4em auto 1.4em;
}
@media (max-width: 649px) {
  .dropcap-first .wiki-art { float: none; width: 62%; margin: 0 auto 1.2em; }
  .dropcap-first .wiki-art:has(> img) { width: min(100%, 30rem); }
}

ul, ol { font-size: 0.95rem; line-height: 1.63; padding-left: 1.4em; margin: 0 0 1em; }
li { margin-bottom: 0.3em; }

blockquote {
  margin: 1em 0;
  padding: 0.6em 1em;
  border-left: 1px solid var(--quote-rule);
  background: var(--panel);
  font-size: 0.92rem;
}
blockquote blockquote { border-left-color: var(--quote-rule-2); background: var(--quote-bg-2); }
blockquote blockquote blockquote { border-left-color: var(--quote-rule-3); background: var(--quote-bg-3); }

code {
  font-family: "IBM Plex Mono", Menlo, Consolas, monospace;
  font-size: 0.75rem;
  border: 1px solid var(--rule-soft);
  background: var(--panel);
  padding: 1px 4px;
}
pre { overflow-x: auto; border: 1px solid var(--rule-soft); background: var(--panel); padding: 12px; }
pre code { border: 0; padding: 0; }

table { border-collapse: collapse; font-size: 0.85rem; margin: 0 0 1em; }
th, td { border-bottom: 1px solid var(--rule-soft); padding: 5px 12px 5px 0; text-align: left; }
th { font-variant: small-caps; }

.prov { color: var(--faint-ink); font-size: 0.85em; }

/* ---------------- expand — the garage, full screen ---------------------
   Nothing clever: the well goes fullscreen, so the nav and the browser
   chrome fall away and only the garage is left. Ratio is not forced, so
   black may show above or below — that is the honest result. */

.door-tools {
  position: absolute;
  right: clamp(6px, 0.6vw, 12px);
  bottom: clamp(6px, 0.6vw, 12px);
  z-index: 4;
  display: flex;
  flex-direction: row;
  align-items: center;
  /* it belongs to the room, so it only exists once the room is showing */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease;
}
#expand, #print {
  /* MINIMAL since 2026-09-01 (Emil: "youtube like"): no key material, no
     plate, no shadow — just the mark, quiet until hovered. The 44px box
     stays for the thumb; only the glyph is drawn. Print sits to the left
     of expand, same size, same manners (Hierarchy, 2026-09-07). */
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--ink);
}
#print { display: none; }
.door-tools.print-on #print { display: grid; }
/* awake = the pointer moved in the last two seconds (theme.js); the cluster
   is otherwise invisible so it never sits on a page's content */
.well.open .door-tools { pointer-events: auto; }
.well.open.awake .door-tools,
.well.open .door-tools:focus-within { opacity: 0.55; transition: opacity 0.15s ease; }
.well.open .door-tools:hover { opacity: 1; }
/* corners point out at rest; in full screen the :fullscreen/.faux-fs rules
   below swap them to point in */
#expand .ico-in { display: none; }
/* 22 -> 25, and the stroke 2.2 -> 1.5 in theme.js: bigger mark, lighter line.
   The 30px button is unchanged -- that is the touch target, not the glyph. */
#expand svg, #print svg { width: 22px; height: 22px; display: block; }
#expand svg path { transition: transform 0.2s cubic-bezier(0.3, 0.7, 0.4, 1.3); }
/* the brackets pull apart under the cursor — the room opening up */
#expand:hover .ico-out path:nth-child(1) { transform: translate(-1.4px, -1.4px); }
#expand:hover .ico-out path:nth-child(2) { transform: translate(1.4px, -1.4px); }
#expand:hover .ico-out path:nth-child(3) { transform: translate(-1.4px, 1.4px); }
#expand:hover .ico-out path:nth-child(4) { transform: translate(1.4px, 1.4px); }
/* and draw together when it means come back out */
#expand:hover .ico-in path:nth-child(1) { transform: translate(1.4px, 1.4px); }
#expand:hover .ico-in path:nth-child(2) { transform: translate(-1.4px, 1.4px); }
#expand:hover .ico-in path:nth-child(3) { transform: translate(1.4px, -1.4px); }
#expand:hover .ico-in path:nth-child(4) { transform: translate(-1.4px, -1.4px); }
#expand:active, #print:active { transform: scale(0.9); }
#expand .ico-in { display: none; }

/* FULL SCREEN — the garage fills the screen; it is not replaced by the room.
   The old rule promoted `.well` to `position: fixed; inset: 0`, so the nav, the
   cladding and the reveal all vanished and what was left was a bare white page.
   That is the concept surrendering exactly when the site is in use. Now the
   only thing that changes is the air: it goes to 0, the garage becomes the
   whole viewport, and the opening is the largest the garage can give —
   1396x812 at 1440x900, 28 lines against 19.7 at rest.

   The scene is `100vw` wide and `100dvh - 2*--air` tall, so `--air: 0` alone
   makes it fill the screen; nothing needs to be positioned. Both paths are
   covered: `:fullscreen` for the real browser API (requested on the scene, see
   theme.js) and `.faux-fs` for when it is refused. */
.scene.garage:fullscreen,
.scene.garage:has(.well.faux-fs) { --air: 0px; }
.scene.garage:has(.well.faux-fs) { position: fixed; inset: 0; z-index: 80; }
/* The fullscreen element is the scene now, so `.well:fullscreen` can never
   match — these key off the scene. The white-on-black treatment goes with the
   black: the room shows through, so the control keeps its own ink. */
/* in full screen the button keeps the same manners: invisible at rest,
   awake with the pointer -- the general rules above already do that */
.scene.garage:fullscreen #expand .ico-out,
.garage .well.faux-fs #expand .ico-out { display: none; }
.scene.garage:fullscreen #expand .ico-in,
.garage .well.faux-fs #expand .ico-in { display: block; }
body.stage-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { #expand, #print, #expand svg path, .scene.garage, .door-tools { transition: none; } }

/* ---------------- social — the tier list, its icons clickable ----------
   Same idea as the room: the picture is the interface. Only the platforms
   Emil is actually on carry a link. */


/* ---------------- the wiki catalogue, in the well ---------------------- */

/* ---------------- the room's opening sentence --------------------------
   Built 2026-08-23, pulled the same day ("the nav is enough" — a line
   NAMING the room said it twice), kept unused, and back in service
   2026-08-30: the Socials board opens with Emil's line about attention.
   A sentence that says something is not a title.

   The shape: one <p class="room-head"> as the first child of whatever
   establishes the room's measure (inside `main`, or the pane for the tier
   board), matched to the Books page — Fraunces 24px/500, centred in a 672px
   measure, raised first letter, 32px above and 40px below. */
:root { --room-head-above: 32px; --room-head-gap: 40px; }
.room-head {
  margin: 0 auto var(--room-head-gap);
  max-width: 672px;
  text-align: center;
  font-family: "Fraunces", var(--serif);
  font-size: 24px;
  line-height: 1.375;
  font-weight: 500;
  color: var(--ink);
  text-wrap: balance;
}
.room-head::first-letter { font-size: 1.4em; line-height: 1; }
.pane.tier > .room-head { padding: var(--room-head-above) 40px 0; }
@media (max-width: 649px) {
  :root { --room-head-above: 24px; --room-head-gap: 32px; }
  .room-head { font-size: 20px; }
  .pane.tier > .room-head { padding: var(--room-head-above) 12px 0; }
}

.pane.wikipane { background: var(--bg); }
/* the index is a directory, not prose: it may run wider than the reading
   measure — the garage window already holds it off the screen edges */
/* The room is seen THROUGH an opening with a physical reveal, and the reveal
   darkens the top ~22px of it. Content starting at 14px began inside that
   shadow (tasks.md O.8) and read as crowded against the frame. A window wants
   a visible margin, so the page reads as sitting inside something. */
.pane.wikipane main { max-width: 1060px; padding: 34px 40px 48px; }
/* the index is the exception to the exception: the contents belong against
   the left edge of the window, so it drops the measure entirely */
.pane.wikipane main.index-page { max-width: none; padding: 34px 44px 48px; }
/* the top gap is the page padding plus the rail's own margin; keeping that
   sum equal to the side padding makes one even gutter round three sides */
.pane.wikipane header.masthead { margin-top: 1.4em; }
/* Fullscreen rooms breathe (Emil, 2026-08-29, "inspired by gwern"): with
   the air gone the pane IS the viewport, so documents get their margin back
   INSIDE it — a centered measure with real space left and right. Drawn
   rooms (tier list) and iframed rooms already own their own layout. */
.scene.garage:fullscreen .pane.wikipane main,
.scene.garage:has(.well.faux-fs) .pane.wikipane main { margin-left: auto; margin-right: auto; }
.scene.garage:fullscreen .pane.wikipane main.index-page,
.scene.garage:has(.well.faux-fs) .pane.wikipane main.index-page {
  max-width: 1180px;
  padding-left: clamp(24px, 6vw, 110px);
  padding-right: clamp(24px, 6vw, 110px);
}

/* A fixed-proportion hierarchy: visual weight increases toward the base.
   On phones the same overview is paired with readable descriptions below. */
.pane.wikipane:has(> .wiki-ehh) { display: flex; flex-direction: column; }
.pane.wikipane main.wiki-ehh,
.scene.garage:fullscreen .pane.wikipane main.wiki-ehh,
.scene.garage:has(.well.faux-fs) .pane.wikipane main.wiki-ehh {
  position: relative; max-width: none; width: 100%; height: 100%; min-height: 540px;
  margin: 0; padding: 38px 48px 38px; box-sizing: border-box; flex: 1;
}
.wiki-ehh .crumb {
  position: absolute; top: 14px; left: 28px; z-index: 2;
  font-size: 0.75rem; color: var(--meta-ink); background-image: none; text-shadow: none;
}
.wiki-ehh .crumb:hover { color: var(--ink); }
.ehh {
  --ehh-attention: #a92323;
  --ehh-people: #e05d2d;
  --ehh-sleep: #e68536;
  --ehh-movement: #e6a83d;
  --ehh-nutrition: #99ac7d;
  --ehh-surroundings: #5e8b84;
  --ehh-on-deep: #fff8f5;
  --ehh-ink: #24271e;
  position: relative; height: 100%; min-height: 464px; container-type: size;
}
.ehh-title {
  position: absolute; top: 7%; left: 0; width: 29%; text-align: left;
  margin: 0; padding: 0; font-family: var(--serif); font-weight: 500;
  font-size: clamp(25px, 3.2cqw, 44px); line-height: 1.1;
  letter-spacing: -0.035em; color: var(--ink);
  font-variant: normal; text-transform: none; border: 0;
}
.ehh-title .ehh-of { display: block; }
.ehh-pyramid {
  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
  width: min(100%, calc(100cqh * 1.65)); height: auto; aspect-ratio: 1.65;
  margin: 0; padding: 0; list-style: none; container-type: size;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  print-color-adjust: exact; -webkit-print-color-adjust: exact;
}
.ehh-band {
  position: absolute; top: var(--top); left: 0; width: 100%; height: calc(var(--height) - 3px);
  box-sizing: border-box; display: flex; align-items: center; justify-content: center;
  gap: 2%; padding: 0; background: var(--band); color: var(--ehh-ink); text-align: left;
  transition: background-color 180ms ease;
  --edge: calc(50% - var(--top) / 2 - var(--height) / 4);
}
.ehh-band:nth-child(1) { --ehh-rank: 5; --top: 79%; --height: 21%; --band: var(--ehh-attention); color: var(--ehh-on-deep); height: 21%; }
.ehh-band:nth-child(2) { --ehh-rank: 4; --top: 61%; --height: 18%; --band: var(--ehh-people); }
.ehh-band:nth-child(3) { --ehh-rank: 3; --top: 47%; --height: 14%; --band: var(--ehh-sleep); }
.ehh-band:nth-child(4) { --ehh-rank: 2; --top: 35%; --height: 12%; --band: var(--ehh-movement); }
.ehh-band:nth-child(5) { --ehh-rank: 1; --top: 24%; --height: 11%; --band: var(--ehh-nutrition); }
.ehh-band:nth-child(6) {
  --ehh-rank: 0; --top: 0%; --height: 24%; --band: var(--ehh-surroundings);
  flex-direction: column; justify-content: flex-end; gap: 2%; padding-bottom: 0.7%;
}
.ehh-copy { position: absolute; left: calc(var(--edge) + 11%); right: var(--edge); display: flex; flex-direction: column; align-items: flex-start; gap: 0.22em; min-width: 0; }
.ehh-name {
  font-family: var(--serif); font-weight: 500; font-size: calc(1.8cqw + var(--ehh-rank) * 0.2cqw);
  line-height: 1.06; letter-spacing: -0.025em;
}
.ehh-line { font-family: var(--serif); font-size: 1.75cqw; font-weight: 400; font-style: normal; line-height: 1.2; }
/* Symbol sizes descend in equal steps while keeping the edge inset. */
.ehh-mark { position: absolute; left: calc(var(--edge) + 3%); top: 50%; transform: translateY(-50%); width: calc(4% + var(--ehh-rank) * 0.25%); height: calc(4cqw + var(--ehh-rank) * 0.25cqw); display: flex; align-items: center; justify-content: center; }
.ehh-mark svg { display: block; width: 100%; height: 100%; }
.ehh-band:nth-child(5) .ehh-line { font-size: 1.35cqw; }
.ehh-band:hover, .ehh-band:focus-visible { background: color-mix(in srgb, var(--band), var(--ehh-on-deep) 12%); }
.ehh-band:focus-visible { outline: none; }
@media (prefers-reduced-motion: reduce) { .ehh-band { transition: none; } }
.ehh-band[data-band="surroundings"] .ehh-mark { position: static; transform: none; flex: none; width: 4%; height: 4cqw; }
.ehh-band[data-band="surroundings"] .ehh-copy { position: static; width: 20%; gap: 0.1em; align-items: center; text-align: center; }
.ehh-band[data-band="surroundings"] .ehh-line { font-size: 1.25cqw; }
.ehh-details { display: none; }
@media (max-width: 649px) {
  .pane.wikipane main.wiki-ehh.wiki-ehh { height: auto; padding: 55px 24px 32px; min-height: 0; }
  .wiki-ehh .crumb { left: 24px; }
  .ehh { height: auto; min-height: 0; container-type: inline-size; }
  .ehh-title { position: absolute; top: 0; width: 34%; font-size: 21px; margin: 0; }
  .ehh-title .ehh-of { display: block; }
  .ehh-pyramid { position: relative; bottom: auto; left: auto; transform: none; width: 100%; aspect-ratio: 1.1; }
  .ehh-band .ehh-line { display: none; }
  .ehh-band .ehh-name { font-size: calc(2.9cqw + var(--ehh-rank) * 0.4cqw); }
  .ehh-band[data-band="surroundings"] .ehh-copy { width: 20%; }
  .ehh-details { display: grid; gap: 0; margin: 30px 0 0; padding: 0; text-align: center; }
  .ehh-detail { padding: 18px 8px; border-top: 1px solid var(--rule-soft); }
  .ehh-detail:nth-child(1) { --ehh-rank: 5; }
  .ehh-detail:nth-child(2) { --ehh-rank: 4; }
  .ehh-detail:nth-child(3) { --ehh-rank: 3; }
  .ehh-detail:nth-child(4) { --ehh-rank: 2; }
  .ehh-detail:nth-child(5) { --ehh-rank: 1; }
  .ehh-detail:nth-child(6) { --ehh-rank: 0; }
  .ehh-detail dt { font: 500 calc(19px + var(--ehh-rank) * 1px)/1.15 var(--serif); margin: 0 0 5px; color: var(--ink); }
  .ehh-detail dd { font: 400 16px/1.4 var(--serif); margin: 0; color: var(--ink); }
}

/* A poster page: the bitmap IS the article. Kept for any future file;
   Hierarchy left this for HTML tiles on 2026-09-07. */
.pane.wikipane:has(> .wiki-poster) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pane.wikipane main.wiki-poster {
  position: relative;
  max-width: none;
  width: 100%;
  flex: 1;
  min-height: 0;
  height: 100%;
  padding: 0;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}
.scene.garage:fullscreen .pane.wikipane main.wiki-poster,
.scene.garage:has(.well.faux-fs) .pane.wikipane main.wiki-poster {
  max-width: none;
  margin: 0;
  height: 100%;
  padding: 0;
}
.wiki-poster .crumb {
  position: absolute; top: 0.9em; left: 1.2em; z-index: 1;
  font-size: 0.7rem; font-variant: small-caps; letter-spacing: 0.06em;
  color: var(--meta-ink); background-image: none; text-shadow: none;
}
.wiki-poster .crumb:hover { color: var(--ink); }
.pane.wikipane main.wiki-poster header.masthead {
  position: absolute;
  top: 0; right: 0; left: 0;
  z-index: 1;
  margin: 0;
  padding: 0.9em 1.2em;
  text-align: right;
  pointer-events: none;
}
.wiki-poster header.masthead a { pointer-events: auto; }
.wiki-poster header.masthead h1 {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.wiki-poster header.masthead .page-metadata {
  justify-content: flex-end;
  margin: 0;
}
.wiki-poster .wiki-art {
  position: absolute;
  inset: 0;
  float: none;
  width: auto;
  max-width: none;
  margin: 0;
  padding: 38px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wiki-poster .wiki-art img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  display: block;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}
.wiki-print {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: 0.45em;
  transform: translateX(-50%);
  padding: 0.35em 0.8em;
  font: inherit;
  font-size: 0.7rem;
  font-variant: small-caps;
  letter-spacing: 0.06em;
  color: var(--meta-ink);
  background: none;
  border: 0;
  cursor: pointer;
}
.wiki-print:hover { color: var(--ink); }

/* ---------------- the socials tier list, drawn not photographed --------
   Six equal rows fill the room's height; the label cell and the tiles are
   sized off the row height, so tiles stay square whatever shape the room
   is. Colours are sampled off Emil's original; the marks are Simple Icons
   (CC0) so they stay crisp and can take the theme. */

/* The rooms all share one background: no board colour, no pastel bands.
   The tiers are told apart by a fine raster of hairlines, the way the rest
   of the site draws structure. The brand fills stay — they are the content,
   not decoration. */

.pane.tier {
  background: var(--bg);
  overflow: hidden;
  padding: 0;
  /* a column, so the sentence takes what it needs and the board takes the
     rest -- the board used to be height:100% of the pane and left no room */
  display: flex;
  flex-direction: column;
}
.board {
  display: grid;
  /* minmax(0, 1fr), not 1fr: `1fr` is `minmax(auto, 1fr)` and that auto floor
     is the row's own content, so the six rows refused to shrink when the
     opening sentence took the top 135px and the last row was clipped by the
     pane's overflow. Same trap as the wiki index's column (tasks.md O.1). */
  grid-template-rows: repeat(6, minmax(0, 1fr));
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  background: var(--bg);
}
/* The single implicit row was `auto`, so .titems sized it from the tiles and
   then overflowed .trow's own box: the tiles measured 109px inside a 95px row
   long before the opening sentence existed -- they spilled across the band
   borders and nobody had measured it. minmax(0,1fr) gives the row the trow's
   definite height, so the label and the tiles finally scale WITH the band.
   Found because the sentence took 135px off the board and made 109-in-73
   impossible to miss. */
.trow {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: minmax(0, 1fr);
  min-height: 0;
}
.trow + .trow { border-top: 1px solid var(--rule-soft); }
.tlabel {
  aspect-ratio: 197 / 145;      /* the label cell's proportion in the original */
  height: 100%;
  display: grid;
  place-items: center;
  border-right: 1px solid var(--rule-soft);
  background: var(--c);
  color: var(--tier-ink, #17170f);   /* the band carries the tier colour; the letter stays ink */
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: clamp(9px, 1.55vw, 25px);
  font-weight: 400;
  line-height: 1.15;
  text-align: center;
}
.tlabel.small { font-size: clamp(6px, 0.92vw, 15px); }
.titems { display: flex; min-width: 0; }
.tile {
  aspect-ratio: 1;
  height: 100%;
  flex: none;
  display: grid;
  place-items: center;
  border-right: 1px solid var(--rule-soft);
  background: var(--fill);
  color: var(--ink);
  text-decoration: none;
  position: relative;
}
.tile svg { width: 60%; height: 60%; fill: currentColor; display: block; overflow: visible; }
/* only the ones that lead somewhere invite a click. The hover LIGHTS the
   tile up (Emil, 2026-08-30: no zoom) — brightness on the whole tile plus
   the accent edge; nothing moves, nothing escapes its row. */
a.tile { transition: filter 0.16s ease; }
a.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  outline: 0 solid var(--acc);
  outline-offset: -1px;
  transition: outline-width 0.14s ease;
}
a.tile:hover, a.tile:focus-visible { filter: brightness(1.25) saturate(1.08); }
a.tile:hover::after, a.tile:focus-visible::after { outline-width: 3px; }
/* Phone: the rows are TALLER than the opening is wide, and a tile takes its
   width from the row's height (aspect-ratio: 1) — 123px tiles in a 370px
   row clipped the board on the right (W.2, found 2026-08-27). The label
   gives up its desktop aspect for a fixed band and the tiles cap at 17vw:
   label 24vw + 4 tiles x 17vw = 92vw, inside any phone opening. */
@media (max-width: 649px) {
  .tlabel { aspect-ratio: auto; width: min(24vw, 96px); }
  .titems { align-items: center; }
  .tile { height: min(100%, 17vw); }
}
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }



/* ---------------- new — the short dated list ----------------------------
   A star, the title, and the day at the end of the line. The date is on
   every row, so the list needs no year above it. */

/* 3.2em existed to hold the newest list off the lede that used to sit above
   it inside .index-head. The lede is the room's opening sentence now and has
   moved out of that box, so on the index the margin is orphaned -- it was
   pushing the list 35px further down than the sentence's own 34px gap.
   This is also tasks.md O.4: the same 3.2em is 57.6px at the phone's font
   size, 10% of a 604px opening, and it was flagged as "authored against a
   desktop pane". First-child now zeroes it in both places at once. */
.latest { margin-top: 4em; }   /* Emil, 2026-08-30: a touch more air off the lede */
.index-head > .latest:first-child { margin-top: 0; }
.latest h2 { margin-top: 0; }
/* the heading is the way in: the short list is the head of the full one */
main .latest h2 a, main .latest h2 a:visited {
  color: inherit;
  background-image: none;
  text-shadow: none;
}
main .latest h2 a::after { content: " \2192"; color: var(--soft-ink); font-size: 0.8em; }
main .latest h2 a:hover { color: var(--link-hover); }

/* the year over each group on the full list */
.year {
  text-align: right;
  font-variant: normal;
  font-size: 1.2rem;
  font-weight: 600;
  margin: 1.8em 0 0;
  padding-bottom: 0.12em;
  border-bottom: 1px solid var(--rule-soft);
}
ul.dated {
  list-style: none;
  margin: 0.9em 0 0;
  padding: 0 0 0 1.4em;
}
ul.dated li {
  display: flex;
  align-items: baseline;
  gap: 0.5em;
  margin: 0.5em 0;
  font-size: 0.95rem;
}
ul.dated li::before {
  content: "";
  flex: none;
  width: 0.62em;
  height: 0.62em;
  background: var(--ink);
  mask: var(--orn-star) center / contain no-repeat;
  -webkit-mask: var(--orn-star) center / contain no-repeat;
  opacity: 0.75;
}
ul.dated .when {
  margin-left: auto;
  padding-left: 1em;
  font-size: 0.8rem;
  color: var(--soft-ink);
  font-variant-numeric: lining-nums tabular-nums;
  white-space: nowrap;
}

/* ---------------- the wiki index: a book that knows the date ------------
   The contents run down the left in a quiet grey box — gwern's, in this
   site's colours: a sans face so it reads as apparatus rather than prose,
   numbers in grey, the whole thing sticky and never taller than the window
   it sits in. The text starts to its right; the newest sits at its foot. */

.index-grid {
  display: grid;
  grid-template-columns: minmax(176px, 232px) 1fr;
  gap: 0 40px;
  align-items: start;
}
/* the contents and the head of the page share the first row; everything
   filed sits in the second and runs the full width, so the page opens out
   once the rail has scrolled past */
.toc { grid-column: 1; grid-row: 1; }
.index-head { grid-column: 2; grid-row: 1; }
.index-body { grid-column: 1 / -1; grid-row: 2; }
@media (max-width: 649px) {
  /* `1fr` is `minmax(auto, 1fr)`, and the `auto` floor is the widest child's
     min-content — here `.index-head`, whose floated 4.6em drop cap plus its
     longest word will not go below 226px. In a 202px grid the column simply
     overflowed and the frame clipped every line's last word. `minmax(0, 1fr)`
     is what lets a column be as narrow as the box holding it. */
  .index-grid { grid-template-columns: minmax(0, 1fr); }
  /* 24px of side padding is 2% of a 1144px opening and 19% of a 250px one. A
     fixed padding cannot serve both; the phone gets its own. */
  /* a phone opening is 250px wide - the same margin in px would be a third of
     it, so the phone gets its own, smaller but still clear of the reveal */
  .pane.wikipane main.index-page { padding: 22px 16px 34px; }
  .pane.wikipane main { padding: 22px 16px 34px; }
  .pane.wikipane main.wiki-poster,
  .pane.wikipane main.wiki-ehh { padding: 0; }
  .wiki-poster .wiki-art { padding: 16px; }
  .toc, .index-head, .index-body { grid-column: 1; grid-row: auto; }
  /* the height overrides live below, after the rules they override */
}

.toc {
  /* the height of one window, level with the text beside it — and it
     scrolls away with the page rather than following it down */
  margin-top: 10px;
  height: calc(var(--pane-h, 100vh) - 72px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* calm paper (Emil, 2026-09-02): the site's grain soft-lit over the panel,
     scrolling with the words (attachment local) */
  background: var(--grain) 0 0 / 160px 160px local, var(--panel);
  background-blend-mode: soft-light, normal;
  border: 1px solid var(--rule-soft);
  padding: 16px 18px;
  font-family: "Source Sans 3", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.toc ol { list-style: none; margin: 0; padding: 0; }
.toc li { margin: 0.3em 0; font-size: 0.7rem; line-height: 1.3; }
.toc .c { color: var(--softer-ink, #aaa); margin-left: 0.4em; font-variant-numeric: lining-nums; font-size: 0.9em; }
.toc-l1 > li { margin-bottom: 0.6em; }
.toc-l1 > li > a { font-weight: 600; font-size: 0.8rem; }
.toc-l2 { margin: 0.3em 0 0 1.15em; }
main .toc a { background-image: none; text-shadow: none; color: var(--ink); }
main .toc a:hover { color: var(--link-hover); text-decoration: underline; }
/* EHH — not a shelf. Distilled learnings, pinned above Health / Life. */
.toc-l1 > li.pin {
  margin: 0 0 1.15em;
  padding: 0.1em 0 0.85em 0.7em;
  border-left: 2px solid var(--acc);
  border-bottom: 1px solid var(--rule-soft);
}
.toc-l1 > li.pin > a {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.18em;
  font-weight: 400;
  font-size: inherit;
}
.toc-l1 > li.pin .ehh-kicker {
  font-family: var(--serif);
  font-weight: 650;
  font-size: 0.95rem;
  font-variant: small-caps;
  letter-spacing: 0.14em;
  line-height: 1.1;
}
.toc-l1 > li.pin .ehh-note {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 0.68rem;
  letter-spacing: 0;
  color: var(--faint-ink);
  line-height: 1.35;
}
main .toc .pin a:hover { text-decoration: none; }
main .toc .pin a:hover .ehh-kicker { color: var(--link-hover); text-decoration: underline; }
main .toc .pin a:hover .ehh-note { color: var(--meta-ink); }

/* two equal halves, ending level with the contents beside it: the lede sits
   in the top one and the newest starts at the midline of the window */
.index-head {
  padding-top: 10px;
  height: calc(var(--pane-h, 100vh) - 62px);
  display: grid;
  /* the lede's row is its own height; the newest list follows it at a fixed
     3.2em gap (.latest margin). fr rows with auto floors resized chaotically
     here — row 2's content floor fed back into the fr unit. */
  grid-template-rows: auto minmax(0, 1fr);
}
/* .index-head .lede -- gone: the lede is now .pane > .room-head, above the grid. */
/* Phone: drop the one-window heights. This block must sit *after* the two rules
   above — `.toc` and `.index-head` are both single-class selectors, so an override
   of equal specificity only wins by source order. Written above them it loses
   silently, which is what happened: the `height: auto` beside the phone grid was
   dead from the day it was written, and both blocks kept their desktop calc. The
   rail held 19px of content open to 532px of a 604px opening.

   The one-window height is a property of the *two-column layout*, not of these
   blocks: a rail beside text must not outrun the text, or two scroll axes fight.
   Stacked on a phone there is no beside, so the cap is only a lid. */
@media (max-width: 649px) {
  .toc { height: auto; overflow: visible; }
  .index-head { height: auto; display: block; }
}



/* the star between the newest and everything filed below it */
hr.star {
  border: 0;
  height: 26px;
  margin: 2.2em 0 1.8em;
  background: var(--ink);
  mask: var(--orn-star) center / 22px no-repeat;
  -webkit-mask: var(--orn-star) center / 22px no-repeat;
  opacity: 0.55;
}

.cat h3 {
  font-size: 0.95rem;
  font-weight: 600;
  font-variant: small-caps;
  letter-spacing: 0.02em;
  margin: 1.4em 0 0.2em;
  color: var(--link);
}
.cat h3 .cat-n { font-variant: normal; letter-spacing: 0; font-size: 0.8em; color: var(--soft-ink); }

/* ---------------- settings — a page behind the curtain like any other --- */

.pane.settings {
  background: var(--bg);
  color: var(--ink);
  padding: 5% 8% 6%;
  display: flex;
  flex-direction: column;
  gap: 1.6em;
}
.pane.settings h2 { max-width: 420px; }
/* The scene picker is a row of PAINT CHIPS hanging on nails — samples of the
   material each scene is made of, drawn in CSS. The chip says what the word
   cannot: what the world will look like. The chosen chip hangs straight;
   the others hang a touch crooked, the way samples on a wall do. A scene id
   with no .chip-<id> rule falls back to plain paper, so a new scene is never
   an invisible button. */
.settings .theme-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.settings .scene-row { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.settings .scene-note {
  margin: 0.45em 0 0;
  font-size: 0.85rem;
  color: var(--rule);
}
.settings .theme-row button {
  font: inherit;
  font-variant: small-caps;
  font-size: 15px;
  color: var(--link);
  background: none;
  border: 1px dotted transparent;
  padding: 3px 10px;
}
.settings .theme-row button:hover { color: var(--ink); border-color: var(--link); }
.settings .theme-row button.on { border: 1px solid var(--rule); }
.settings .scene-row button {
  font: inherit;
  background: none;
  border: 0;
  padding: 4px 2px;
  display: grid;
  justify-items: center;
  gap: 5px;
  cursor: pointer;
  transform: rotate(-1.6deg);
  transform-origin: 50% 4px;   /* it swings about its nail */
  transition: transform 0.16s cubic-bezier(0.3, 0.7, 0.4, 1.35);
}
.settings .scene-row button:nth-child(even) { transform: rotate(1.4deg); }
.settings .scene-row button.on,
.settings .scene-row button:hover { transform: rotate(0deg); }
.settings .scene-row button:focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; border-radius: 4px; }
.settings .chip, .nav-settings .chip {
  position: relative;
  width: 58px;
  height: 44px;
  border-radius: 3px;
  border: 1px solid var(--chip-edge, rgba(0, 0, 0, 0.28));
  background: var(--paper-card);   /* the plain-paper default */
  box-shadow: var(--chip-cast, 0 2px 3px rgba(0, 0, 0, 0.22));
}
.settings .chip::before, .nav-settings .chip::before {   /* the nail hole the chip hangs from */
  content: "";
  position: absolute;
  top: 3px;
  left: 50%;
  width: 5px;
  height: 5px;
  margin-left: -3px;
  border-radius: 50%;
  background: var(--chip-hole, rgba(0, 0, 0, 0.45));
}
.settings .chip-modern, .nav-settings .chip-modern {
  background:
    linear-gradient(
      var(--chip-modern-hi, #eceef0) 0 31%, var(--chip-modern-lo, #cfd3d7) 31% 34%,
      var(--chip-modern-hi, #eceef0) 34% 64%, var(--chip-modern-lo, #cfd3d7) 64% 67%,
      var(--chip-modern-hi, #eceef0) 67%);
}
.settings .chip-atelier, .nav-settings .chip-atelier {
  background: repeating-linear-gradient(90deg, var(--chip-oak-seam, #87633d) 0 1px, transparent 1px 12px), linear-gradient(115deg, var(--chip-oak-hi, #d9b27b), var(--chip-oak-lo, #a97b48));
}
.settings .chip-basalt, .nav-settings .chip-basalt {
  background: repeating-linear-gradient(0deg, transparent 0 15px, var(--chip-stone-seam, #39433e) 15px 16px), linear-gradient(115deg, var(--chip-stone-hi, #839089), var(--chip-stone-lo, #47534c));
}
.settings .chip-brick, .nav-settings .chip-brick {
  /* a miniature of the brick scene's own wall tile: offset courses, the
     wall's real colours, mortar between — not stripes */
  background:
    url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%2740%27%20height%3D%2720%27%3E%3Crect%20width%3D%2740%27%20height%3D%2720%27%20fill%3D%27%238a8074%27%2F%3E%3Crect%20x%3D%270%27%20y%3D%270%27%20width%3D%2719%27%20height%3D%279%27%20fill%3D%27%238d5e50%27%2F%3E%3Crect%20x%3D%2720%27%20y%3D%270%27%20width%3D%2719%27%20height%3D%279%27%20fill%3D%27%23825347%27%2F%3E%3Crect%20x%3D%27-10%27%20y%3D%2710%27%20width%3D%2719%27%20height%3D%279%27%20fill%3D%27%23996958%27%2F%3E%3Crect%20x%3D%2710%27%20y%3D%2710%27%20width%3D%2719%27%20height%3D%279%27%20fill%3D%27%23754b41%27%2F%3E%3Crect%20x%3D%2730%27%20y%3D%2710%27%20width%3D%2719%27%20height%3D%279%27%20fill%3D%27%23996958%27%2F%3E%3C%2Fsvg%3E"),
    var(--chip-brick, #8d4a3a);
}
.settings .chip-label {
  font-variant: small-caps;
  font-size: 13px;
  color: var(--link);
}
.settings .scene-row button.on .chip { outline: 2px solid var(--acc); outline-offset: 1px; }
.settings .scene-row button.on .chip-label,
.settings .scene-row button:hover .chip-label { color: var(--ink); }
.settings .contact {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 420px;
}
.settings .contact textarea,
.settings .contact input {
  font: inherit;
  font-size: 0.75rem;
  color: var(--ink);
  background: var(--panel);
  border: 1px dotted var(--rule-soft);
  padding: 6px 8px;
  resize: vertical;
}
.settings .contact .row { display: flex; align-items: center; gap: 8px; }
.settings .contact .status { font-size: 0.65rem; color: var(--faint-ink); flex: 1; }
.settings .contact button[type="submit"] {
  font: inherit;
  font-size: 0.75rem;
  font-variant: small-caps;
  color: var(--link);
  background: none;
  border: 1px dotted var(--link);
  padding: 3px 14px;
}
.settings .contact button[type="submit"]:hover { color: var(--ink); border-style: solid; }

/* ---------------- face animation (mechanic from emilmeggle.me) ---------- */

.face path { transform-box: fill-box; transform-origin: center; }
.face path[data-f="brow"] { transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1); }
.face[data-expression="blink"] path[data-f="eye-left"],
.face[data-expression="blink"] path[data-f="eye-right"] {
  animation: face-blink 280ms cubic-bezier(0.22, 1, 0.36, 1);
}
.face[data-expression="suspicious"] path[data-f="brow"] {
  transform: translateY(7%) rotate(-9deg);
}
@keyframes face-blink {
  0%, 100% { transform: scaleY(1); }
  50%      { transform: scaleY(0.08); }
}
@media (prefers-reduced-motion: reduce) {
  .face path { animation: none !important; transition: none !important; }
}
/* the inlined SVG replaces the <img>: same box. The face is drawn in
   currentColor, and its ink is the CLADDING's ink — it is a mark on the
   wall, so it follows the wall's light like every key label. The old fixed
   #111 was a colour literal in a garage rule (the leak §9 forbids): found
   2026-08-27 at 1.3:1 against city-bar's dark key, an invisible face. */
#navbar .logo svg.logo-img { filter: none; color: var(--clad-ink, #111); display: block; }


/* ---------------- the rooms behind the one door ------------------------
   Every section the cassette can play lives in the frame at once and only
   one is visible. They stay in the DOM on purpose: a key press swaps which
   room shows, so nothing is ever rebuilt and the embeds keep their state.
   Hidden rooms keep their box — an embed with no box never loads. */

.frame .section { position: absolute; inset: 0; }
.frame .section:not(.on) { visibility: hidden; pointer-events: none; }

/* ---------------- the pane: several embeds stacked inside one window ----
   Each same-origin iframe is sized to its content (theme.js), so the pane
   is the only scroller — one window, everything inside it. */

.frame .pane {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.frame .pane iframe { width: 100%; height: auto; min-height: 320px; border: 0; display: block; }
/* a pane embed fades in over the paper once it has painted (theme.js sets
   and lifts .dim); the paper is what an open door shows until then */
.frame .pane iframe { opacity: 1; transition: opacity 0.45s ease; }
.frame .pane iframe.dim { opacity: 0; transition: none; }
/* A room from the other origin lays itself out against the height it is
   given, so it must never be handed less than the window: it would report
   that smaller height back and settle there. */
.frame .pane iframe.room { min-height: 100%; }

/* ---------------- served by TrainWeek -----------------------------------
   The round badge in the top-right corner of the sports opening: the wall
   is scheduled in TrainWeek and synced over, and this button is the whole
   link to the external tool. Pinned to the FRAME, not the pane, so it
   holds the corner while the room scrolls under it. A maker's mark, not
   an ad — the label slides out on hover/focus only. */
.tw-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;   /* above the pane, BELOW the door (.up, z 2): the badge is
                   part of the room and must not float on the closed door */
  display: flex;
  align-items: center;
  height: 30px;
  padding: 0 6px;
  border-radius: 15px;
  background: var(--bg);
  border: 1px solid var(--ink);
  text-decoration: none;
  color: var(--ink);
  box-shadow: var(--tw-cast, 0 2px 6px rgba(0, 0, 0, 0.18));
}
.tw-btn img { width: 18px; height: 18px; display: block; }
.tw-tip {
  overflow: hidden;
  max-width: 0;
  white-space: nowrap;
  font-size: 11px;
  font-variant: small-caps;
  letter-spacing: 0.06em;
  opacity: 0;
  transition: max-width 0.25s ease, opacity 0.2s ease, margin 0.25s ease;
}
.tw-tip b { font-variant: normal; letter-spacing: 0; }
.tw-btn:hover .tw-tip,
.tw-btn:focus-visible .tw-tip { max-width: 12em; opacity: 0.9; margin-left: 7px; }
.tw-btn:focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; }

/* ---------------- wiki catalog — document cards on the exported index ----
   An entry is its heading and its one line: no icon in front of it. The
   Zierschrift initial belongs to the article it opens. */

.cat h2 .cat-n {
  font-variant: normal;
  letter-spacing: 0;
  font-size: 0.75em;
  color: var(--faint-ink);
}
ul.docs {
  list-style: none;
  padding: 0;
  margin: 0.9em 0 2em;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 40px;
}
@media (max-width: 649px) { ul.docs { grid-template-columns: 1fr; } }
main a.doc {
  display: block;
  color: var(--ink);
  background: none;      /* cancel the prose underline gradient */
  text-shadow: none;
}
main a.doc:visited, main a.doc:hover { color: var(--ink); }
.doc-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.doc-title { font-size: 0.95rem; font-weight: 600; line-height: 1.3; }
.doc:hover .doc-title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.doc-sum  { font-size: 0.8rem; color: var(--link); line-height: 1.45; }
.doc-meta { font-size: 0.8rem; font-variant: small-caps; letter-spacing: 0.05em; color: var(--soft-ink); }

/* ---------------- dropcaps — Deutsche Zierschrift on wiki entries -------- */

/* One rule for all three dropcaps; the landing overrides only its size below. */
.dropcap-first > p:first-of-type::first-letter,
.index-head .lede::first-letter,
.wiki-intro .lede::first-letter,
.pane.landingpane .lede::first-letter {
  font-family: "Deutsche Zierschrift", var(--serif);
  float: left;
  font-size: 4.6em;
  line-height: 0.8;
  padding: 0.04em 0.1em 0 0;
  color: var(--ink);
}

/* ---------------- the keys ---------------------------------------------
   The housing is drawn by the shell SVG behind (see .cassette). These are
   the bands of it that press. */


/* at rest the bar is the plain round cassette — labels, curved slots,
   nothing else. Only on press does a key reveal itself:
   the full band between its dividers sinks back-right into the cylinder,
   its sunken face carved by the divider arcs (parallel circles on the
   tube). */
#navbar .links {
  height: 85%;
  align-items: stretch;
}
#navbar .links a {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.4em;
  border-radius: 0;
  /* opacity rides along for the gear-roll wipe: its per-key delay is set
     inline by theme.js, and a transition list that omits opacity would make
     the wipe instant (this rule outranks the roll block's by source order) */
  transition: transform 0.09s cubic-bezier(0.4, 0, 0.6, 1), opacity 0.18s ease;
}
/* The sunken face lives in its OWN layer (a::after), never on the key
   itself: a mask on the key would clip the key's own slot art away.
   z-index -1 keeps it behind the label and behind the slots.
   It is carved by the SAME arcs the slots draw, in the SAME coordinate
   frame — each edge mask is a 0.55em box placed exactly where that slot's
   art sits, so face and slot can never drift apart. Layer 1 is the left
   edge (everything right of the slot's inner curve), layer 2 the right
   edge, layer 3 the solid middle. --ext lets the face reach a little past
   the slot so the key's travel cannot open a gap. */
#navbar .links a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.09s cubic-bezier(0.4, 0, 0.6, 1),
              transform 0.09s cubic-bezier(0.4, 0, 0.6, 1);
  /* The recess is a straight square cut now (Emil, 2026-08-30: the bowed
     arc strokes read as "weird round curves" mid-press). Left wall shows
     the cut the key travelled away from; right is the thin contact shade
     where it tucks under the lip; then the scene-ownable recess light. */
  background:
    linear-gradient(90deg, var(--recess-wall, rgba(20,20,20,.5)) 0, rgba(20,20,20,0) 100%) 0 0 / 0.5em 100% no-repeat,
    linear-gradient(270deg, var(--recess-contact, rgba(20,20,20,.26)) 0, rgba(20,20,20,0) 100%) right 0 top 0 / 0.3em 100% no-repeat,
    var(--key-recess-light,
      linear-gradient(180deg,
        rgba(0, 0, 0, 0.46) 0%,
        rgba(0, 0, 0, 0.20) 7%,
        rgba(0, 0, 0, 0.05) 26%,
        rgba(0, 0, 0, 0) 42%),
      linear-gradient(0deg,
        rgba(255, 255, 255, 0.46) 0%,
        rgba(255, 255, 255, 0.16) 5%,
        rgba(255, 255, 255, 0) 14%),
      linear-gradient(rgba(0, 0, 0, 0.085), rgba(0, 0, 0, 0.085)));
}

/* the key sinks: the face appears, the whole band travels back-right and
   recedes a hair from the eye */
#navbar .links a:active,
#navbar .links a.pressed {
  /* snappier press, no elastic overshoot (Emil, 2026-08-30) */
  /* Was `#000`. Correct on modern's pale cladding, invisible on a dark one:
     city-bar measured 1.95:1 for the key you are standing on. The ink a
     sunken key takes is a property of the material, so it is the scene's. */
  color: var(--clad-ink-on);
  transform: translate(0.13em, 0.2em);
}
/* the opening in the housing never moves — only the key inside it does.
   The face counter-shifts back into that fixed frame, so it can never
   spill past the slots sideways or past the lips top and bottom. */
#navbar .links a:active::after,
#navbar .links a.pressed::after {
  opacity: 1;
  transform: translate(-0.13em, -0.2em);
}

/* Phone: the tight key padding, restated *after* the nav rules above.
   `#navbar .links a { padding: 0 2px }` is declared with the phone grid near the
   top of this file, but `#navbar .links a` is repeated below it at equal
   specificity with `padding: 0 0.4em`, so the phone value lost on source order and
   the keys have been carrying desktop padding on a phone since it was written.
   Same defect as the wiki rail — see CLAUDE.md. Harmless today, because the labels
   still fit; it would have bitten the first time a longer one was added. */
@media (max-width: 649px) {
  #navbar .links a { padding: 0 2px; }
}

/* ---------------- placeholder ---------------- */

.placeholder {
  border: 1px dotted var(--rule);
  background: var(--panel);
  padding: 40px;
  text-align: center;
  color: var(--faint-ink);
  font-style: italic;
}

/* ---------------- the landing: the door does not open by hand -----------
   The half-open rest state is GONE (Emil, 2026-08-30): the landing door sits
   shut like every other, and a pull on it only heaves —
   see #curtain.heave with the door hardware above. The cassette keys drive
   the motor; that is the only way any of these doors ever moved. */

/* The postkasten used to widen the scene's gutter here. Its markup is out of
   index.html pending the interview (tasks.md 3.1), and the rule referenced the
   bitmap geometry that no longer exists, so it is gone. The air rule owns the
   gutter now. */

/* The grid that split this pane at the half-open door's lip went with the
   half-open door (2026-08-30). The door clears completely now, so the room
   is furnished like any other: one column of text with real air around it. */
.pane.landingpane {
  background: var(--bg);
  /* The lede is longer than the window on most screens, and the pane
     scrolls -- but a line cut dead at the frame's edge reads as broken rather
     than as "there is more". Fading the last few lines says the same thing
     honestly. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - 46px), transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - 46px), transparent 100%);
}
.pane.landingpane main {
  max-width: 640px;
  margin: 0 auto;
  padding: 34px 40px 48px;   /* the wikipane's rhythm — same house */
}
.pane.landingpane p { font-size: 1.02rem; line-height: 1.62; }
.pane.landingpane .lede::first-letter { font-size: 4.2em; }

/* UN-PARKED 2026-08-30: the street objects returned once the scene was a
   scene — the Postkasten stands ON the way now, feet on the
   band's top edge, lit by each scene's own tokens. */


/* ---------------- postkasten -------------------------------------------
   Drawn, not photographed, like the socials tiles — a stroke figure that
   takes --ink and so works on either page colour. It stands in the gutter
   the garage leaves to its left. */
/* The box stands in the AIR, so it is sized BY the air -- never by a magic
   -100px. Air is clamp(24px, 14vmin, 168px) and 14vmin reads the screen's
   SHORT side, so a wide-but-short window (1200x600 -> 84px of air) gave less
   room than the box wanted and it hung off the left of the page. Now it can
   only ever be as wide as the air minus its own margins.
   Declared on `.scene.garage`, where --air is, and NOT on
   `.scene.garage:has(#postkasten)` -- that selector outranks the phone
   override on specificity and has bitten this file before. The height and the
   panel's bottom are DERIVED, so the panel cannot drift off the box. */
.scene.garage {
  /* The box sits EVENLY in the air: the same 16px to the page edge as to the
     garage wall, at every screen. Sizing it against the air with one lump
     reserve did not hold that -- at 1200x600 it left 4px on the outside and
     16px on the inside. Two named gaps, and the margin is an invariant. */
  --pk-gap:  16px;   /* box to the garage wall */
  --pk-edge: 16px;   /* box to the edge of the page */
  /* The slot's width lives HERE, not on #postkasten: .postbox is the slot's
     SIBLING, and a var declared on the button is invisible to it. The 76px
     fallback it fell back to put the grown box 3.6px off the small one and
     fed the wrong width into its bottom formula (found 2026-08-30). */
  --slot-w: max(0px, min(76px, calc(var(--air) - 32px)));
  --pk-w:    max(0px, min(96px, calc(var(--air) - var(--pk-gap) - var(--pk-edge))));
  /* the art's aspect, declared once so the box, the panel's position and the
     drawing can never disagree about the shape */
  --pk-ar:   calc(389.1 / 131.2);   /* the vector's own bounding box */
  --pk-h:    calc(var(--pk-w) * var(--pk-ar));
  /* The box stands on the SAME GROUND as the garage -- both feet on one line,
     which is what makes it read as standing beside the building rather than
     floating next to it. Emil, 2026-08-23. Kept as a token because the panel's
     max-height does arithmetic with it. */
  --pk-foot: 0px;
  /* The box stands at the RIGHT edge and OVERLAPS the building a little
     (Emil, 2026-08-28, sketched): part of it is in front of the wall, and
     that lap plus its cast shadow is what buys the depth. */
  --pk-overlap: 8px;   /* laps the FRAME only, never the door (Emil, 2026-08-28) */
  --pk-right: calc(-1 * (var(--pk-w) - var(--pk-overlap)));
}

#postkasten {
  /* THE LETTER SLOT (Emil, 2026-08-30): set INTO the wall, not standing in
     the street — a plate in the wall plane at letter height, 2D relief
     under the format law. Frame and function first; texture later.
     It lives IN the air, centred between building and viewport edge —
     a plate in the wall never laps the building (Emil's catch). */
  position: absolute;
  right: calc(-1 * (var(--air) + var(--slot-w)) / 2);
  bottom: 30%;
  z-index: 5;
  width: var(--slot-w);
  padding: 0;
  border: 0;
  background: none;
  filter: var(--pk-filter, none);
  cursor: pointer;
}
.slot-plate {
  /* the FULL BOX (Emil, 2026-08-30: "a 2d-3d like box in the wall", not
     just a mouth) — a body with volume told by relief alone: top face lit,
     sides turning away a shade, a real cast down the wall. The slot rides
     high; the front panel below is where read letters will pin. */
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 92 / 124;
  /* the ARCHED TOP is the reference mailbox's tunnel profile (Emil,
     2026-08-30: "a little more like a postbox") — % radii so the grown
     box wears the same silhouette and the FLIP stays pure magnification */
  border-radius: 50% 50% 5px 5px / 16% 16% 5px 5px;
  background: linear-gradient(90deg,
      var(--slot-side, #b7bbbe) 0 4%,
      var(--slot-hi, #dfe1e3) 12% 88%,
      var(--slot-side, #b7bbbe) 96% 100%),
    linear-gradient(180deg, var(--slot-hi, #dfe1e3) 0, var(--slot-lo, #c2c6c9) 100%);
  background-blend-mode: multiply, normal;
  box-shadow:
    inset 0 0 0 1px var(--slot-ring, rgba(0, 0, 0, 0.16)),
    inset 0 2px 0 var(--slot-lip-hi, rgba(255, 255, 255, 0.6)),
    inset 0 -2px 0 var(--slot-lip-lo, rgba(0, 0, 0, 0.2)),
    0 3px 6px var(--slot-cast, rgba(0, 0, 0, 0.28));
}
.slot-mouth {
  position: absolute;
  left: 12%;
  right: 12%;
  top: 14%;
  height: 7.5%;
  border-radius: 2px;
  /* not a bare slit any more: a metal FLAP hangs in the mouth, hinged at
     the top — lit face falling dark as it tips inward, a dark gap above
     and below. The slit alone read as abstract (Emil, 2026-08-30). */
  background: linear-gradient(180deg,
    var(--slot-dark, #191a1c) 0 16%,
    var(--slot-flap-hi, #ced2d5) 26%,
    var(--slot-flap-lo, #83888d) 84%,
    var(--slot-dark, #191a1c) 92% 100%);
  box-shadow:
    inset 0 2px 2px var(--slot-throat, rgba(0, 0, 0, 0.8)),
    inset 0 -1px 0 var(--slot-glint, rgba(255, 255, 255, 0.16));
}
.slot-panel {
  /* the front door of the box: a recessed panel with its own hairline.
     The post horn is cut into this face — visible on the closed slot,
     gone while the grown panel is the letter UI. */
  position: absolute;
  left: 12%;
  right: 12%;
  top: 34%;
  bottom: 12%;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--slot-panel-hi, #d3d6d8) 0, var(--slot-panel-lo, #c0c4c7) 100%);
  box-shadow:
    inset 0 1px 2px var(--slot-panel-in, rgba(0, 0, 0, 0.22)),
    inset 0 -1px 0 var(--slot-glint, rgba(255, 255, 255, 0.25));
}
.pk-horn {
  /* Reference post horn silhouette, etched into the steel. Mask so the fill can be
     --slot-etch (a cut, not printed black) and the glint can sit under
     each stroke the way .pb-q already engraves type. */
  --pk-horn-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%2280%2032%20230%20182%22%3E%3Cpath%20fill-rule%3D%22evenodd%22%20d%3D%22M82%2056%20104%2049C101%2074%20106%2097%20118%20112C106%2071%20136%2033%20180%2033C218%2031%20242%2057%20246%2097L256%2046%20309%2058C303%20128%20253%20177%20194%20177C128%20177%2078%20130%2082%2056ZM181%2054C155%2054%20138%2073%20138%2098C138%20123%20156%20142%20181%20142C207%20142%20225%20123%20225%2098C225%2073%20207%2054%20181%2054Z%22%2F%3E%3Cpath%20d%3D%22M116%20183H145L114%20213H86ZM157%20183H186L155%20213H127ZM194%20183H223L254%20213H225ZM236%20183H265L295%20213H266Z%22%2F%3E%3C%2Fsvg%3E");
  position: absolute;
  inset: 10% 6% 8% 6%;
  background: var(--slot-etch, #5e6367);
  -webkit-mask: var(--pk-horn-mask) center / contain no-repeat;
          mask: var(--pk-horn-mask) center / contain no-repeat;
  filter: drop-shadow(0 1px 0 var(--slot-glint, rgba(255, 255, 255, 0.45)));
  opacity: 0.38;
  pointer-events: none;
  z-index: 0;
}
.postbox .pk-horn {
  opacity: 0;
  transition: opacity 0.14s ease;
}
.postbox.closing .pk-horn { opacity: 0.38; }
.postbox > .pb-view > :not(.pk-horn) { position: relative; z-index: 1; }
#postkasten:hover .slot-plate {
  background: linear-gradient(180deg, var(--slot-hi, #e2e4e6) 0, var(--slot-hover, #ced2d5) 100%);
}
#postkasten:focus-visible { outline: 2px solid var(--acc); outline-offset: 6px; border-radius: 6px; }
/* the little flag is the only colour on it, and it is up when there is post */
#postkasten .pk-art { width: 100%; height: auto; display: block; overflow: visible;
  /* the depth: the box casts onto the wall behind it. On the svg, not the
     button, so it composes with the scene's own --pk-filter light. */
  filter: var(--pk-box-cast, drop-shadow(-4px 5px 6px rgba(0, 0, 0, 0.28))); }

/* the tell: an envelope corner sticking out of the box while letters the
   visitor has not read yet wait inside (never the flag — Emil's rule). */
#pk-peek {
  /* a new public letter STICKS OUT of the mouth until this visitor has
     read it — then it joins the pile at the wall's foot */
  position: absolute;
  left: 20%;
  top: 28%;
  width: 46%;
  height: 24%;
  background: var(--paper-card);
  border: 1px solid var(--faint-ink);
  border-radius: 1px;
  transform: rotate(-4deg);
  transform-origin: 50% 0;
  box-shadow: var(--strip-cast, 0 2px 3px rgba(0, 0, 0, 0.25));
  z-index: 2;
}
#pk-peek[hidden] { display: none; }

/* Three colour groups, three tokens. This is what the vector buys over the
   photograph: a scene can RE-LIGHT the object instead of inheriting one fixed
   black. The flag keeps the reference's red -- it is the signal, and it is the
   one thing on the page allowed a second hue precisely because it means
   something rather than decorates. */
#postkasten .pk-hi   { fill: var(--pk-hi,   #453e3d); }
#postkasten .pk-ink  { fill: var(--pk-ink,  #0a0707); }
#postkasten .pk-flag { fill: var(--pk-flag, #b4221f); }

/* The flag stands UP. That is how the vector draws it and how the reference
   photo has it -- upright is the object's own resting state, not a state we
   put it in. It was rotated down to -90deg to signal an empty box; Emil
   rejected that outright and he is right: the drawing is the drawing.
   The pivot is kept because it is measured and correct if the flag is ever
   animated again -- `transform-box: fill-box` reads against the FLAG GROUP's
   own bbox (198.2 42.8 20.2 70.3), and the boss (202, 111) is 18.9% across
   and 97.1% down it. Getting that wrong once made the flag swing about its
   tip instead of its bolt. */
#postkasten .pk-flag {
  transform-box: fill-box;
  transform-origin: 18.9% 97.1%;
}
/* DESKTOP ONLY, and that is a decision, not a gap. Emil's call 2026-08-23.
   The letters wall is a reading surface and a phone opening is 250px wide;
   a cramped version would be worse than an honest absence. The box also
   stands in the AIR, and a phone has ~55px of it -- there is no outside. */
@media (max-width: 900px) { #postkasten, .postbox { display: none; } }

/* The panel does BOTH jobs — write at the top, read the chain below —
   because the Postkasten is outside the door and there is no room behind the
   door to send anyone to. Redesigned 2026-08-28 (Emil: the writer chooses
   public or private; public letters hang on one chronological chain).
   It scrolls; the garage does not grow to fit it. */
.postbox {
  position: absolute;
  /* THE SAME LETTERBOX, ZOOMED (Emil, 2026-08-30, final spec): identical
     recipe to .slot-plate at ~4.3x — same gradients, ring, lips, side
     shading; mouth at the same 12%/14%/7.5% fractions; the choice of the
     two papers sits ON the front panel, which keeps the panel's own
     12%/34%/12% geometry. Because every part is fractional, the FLIP is a
     pure magnification: nothing moves relative to the box while it grows.
     Bottom-right corner pinned; ratio 92/124 held by width-only sizing. */
  right: calc(-1 * (var(--air) + var(--slot-w)) / 2);
  /* grows from the box's CENTRE (Emil): the grown box's vertical centre
     sits on the small box's centre — and the clamp keeps the whole box ON
     THE WALL. It was hanging 49px into the street: the old cap only knew
     the viewport, not where the wall ends (found 2026-08-30). */
  --pb-w: min(380px, calc(100vw - 28px), calc((100dvh - 2 * var(--air) - 20px) * 92 / 124));
  --pb-h: calc(var(--pb-w) * 124 / 92);
  bottom: clamp(10px,
    calc(30% + var(--slot-w) * 0.674 - var(--pb-h) / 2),
    calc(100% - var(--pb-h) - 10px));
  top: auto;
  z-index: 60;
  width: var(--pb-w);
  aspect-ratio: 92 / 124;
  overflow: hidden;
  transform-origin: bottom right;
  /* the same arched silhouette as .slot-plate, magnified */
  border-radius: 50% 50% 14px 14px / 16% 16% 14px 14px;
  background: linear-gradient(90deg,
      var(--slot-side, #b7bbbe) 0 4%,
      var(--slot-hi, #dfe1e3) 12% 88%,
      var(--slot-side, #b7bbbe) 96% 100%),
    linear-gradient(180deg, var(--slot-hi, #dfe1e3) 0, var(--slot-lo, #c2c6c9) 100%);
  background-blend-mode: multiply, normal;
  box-shadow:
    inset 0 0 0 2px var(--slot-ring, rgba(0, 0, 0, 0.16)),
    inset 0 4px 0 var(--slot-lip-hi, rgba(255, 255, 255, 0.6)),
    inset 0 -4px 0 var(--slot-lip-lo, rgba(0, 0, 0, 0.2)),
    0 10px 22px var(--slot-cast, rgba(0, 0, 0, 0.3));
  font-family: "Source Sans 3", "Helvetica Neue", Helvetica, Arial, sans-serif;
  /* ON THE METAL (Emil, 2026-08-30): the panel is light steel in EVERY
     scene, so the content's inks are the box's own, never the page
     theme's — a night scene's light --ink would vanish on steel. Re-
     declaring the theme tokens here re-inks every descendant rule at
     once instead of touching each of them. */
  --ink: var(--slot-ink, #26292b);
  --rule: var(--slot-etch, #5e6367);
  --rule-soft: var(--slot-etch-soft, #b3b8bb);
  --panel: var(--paper-card);
  --bg: var(--slot-hi, #dfe1e3);
  --link: var(--slot-ink, #26292b);
  color: var(--ink);
}
.postbox::before {
  /* the mouth, magnified with everything else */
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  top: 14%;
  height: 7.5%;
  border-radius: 4px;
  /* the same flap as .slot-mouth, magnified */
  background: linear-gradient(180deg,
    var(--slot-dark, #191a1c) 0 16%,
    var(--slot-flap-hi, #ced2d5) 26%,
    var(--slot-flap-lo, #83888d) 84%,
    var(--slot-dark, #191a1c) 92% 100%);
  box-shadow:
    inset 0 6px 8px var(--slot-throat, rgba(0, 0, 0, 0.8)),
    inset 0 -2px 0 var(--slot-glint, rgba(255, 255, 255, 0.16));
}
.postbox > .pb-view {
  /* the front panel, magnified — and now it CARRIES the content */
  position: absolute;
  left: 12%;
  right: 12%;
  top: 34%;
  bottom: 12%;
  border-radius: 8px;
  background: linear-gradient(180deg, var(--slot-panel-hi, #d3d6d8) 0, var(--slot-panel-lo, #c0c4c7) 100%);
  box-shadow:
    inset 0 2px 5px var(--slot-panel-in, rgba(0, 0, 0, 0.22)),
    inset 0 -2px 0 var(--slot-glint, rgba(255, 255, 255, 0.25));
  padding: 14px;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.postbox > .pb-view[hidden] { display: none; }
/* compacting: the content leaves FIRST, fast (Emil, 2026-08-30) — the box
   that shrinks back into the wall is the bare metal one, like the slot it
   becomes. The paint (panel, mouth, arch) rides the whole shrink. */
.postbox.closing .pb-view > *:not(.pk-horn),
.postbox.closing .postbox-close { opacity: 0; transition: opacity 0.14s ease; }
.postbox[hidden] { display: none; }
.postbox-close {
  /* beside the mouth, not in the top corner: the arch rounded that corner
     away and overflow:hidden clipped the old 10px/24px spot to nothing */
  position: absolute; right: 3.5%; top: 15.5%;
  border: 0; background: none; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--rule);
}
.postbox-close:hover { color: var(--ink); }
.postbox-form { display: flex; flex-direction: column; justify-content: center; gap: 10px; flex: 1 1 auto; min-height: 0; margin: 0; }

/* The letter is written on RULED PAPER: serif, real lines that scroll with
   the text (background-attachment: local is what pins them to the writing,
   not the box). */
.postbox-form textarea {
  width: 100%;
  min-width: 0;
  flex: 1 1 auto;
  min-height: 3.4em;
  padding: 2px 2px 8px;
  font-family: var(--serif);
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--ink);
  background-color: transparent;
  background-image: repeating-linear-gradient(to bottom,
      transparent 0 calc(1.7em - 1px), var(--rule-soft) calc(1.7em - 1px) 1.7em);
  background-position: 0 2px;
  background-attachment: local;
  border: 0;
  resize: none;
}
.postbox-form textarea:focus { outline: none; }
.pb-sign {
  width: 100%;
  min-width: 0;
  padding: 4px 2px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.82rem;
  text-align: right;
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule-soft);
}
.pb-sign:focus { outline: none; border-bottom-color: var(--link); }

/* THE CHOICE IS THE PAPER (design canvas, 2026-08-28): a postcard travels
   open, a waxed envelope is private — culture explains it, so the two drawn
   papers are the only buttons. */
.pb-center { text-align: center; }
/* two cards, one row: 2x108 + 14 = 230px must fit the panel's inner width
   (76% of --pb-w minus 28px padding) or "to Emil" wraps below the fold —
   118px cards lost that fit by 1px the day the box learned to stay on the
   wall (2026-08-30) */
.pb-papers { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; margin: 14px 0 4px; }
.paper {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: center;
  font: inherit;
  color: var(--ink);
}
.paper-art { display: block; width: 108px; height: 71px; position: relative; transition: transform 0.16s cubic-bezier(0.3, 0.7, 0.4, 1.35); }
.card-art { border: 1.5px solid var(--draw-ink); border-radius: 6px; background: var(--paper-card); transform: rotate(-2.5deg); box-shadow: var(--card-cast, 0 6px 12px rgba(0,0,0,0.12)); }
.card-art .pa-divider { position: absolute; left: 56px; top: 9px; bottom: 9px; width: 1px; background: var(--rule-soft); }
.card-art .pa-stamp { position: absolute; right: 8px; top: 8px; width: 17px; height: 20px; background: var(--acc); border: 1px solid var(--draw-ink); border-radius: 2px; }
.card-art .pa-line { position: absolute; height: 1px; background: var(--rule-soft); }
.seal-art { transform: rotate(2deg); }
.seal-art svg { width: 100%; height: 100%; display: block; color: var(--draw-ink); filter: var(--card-cast, drop-shadow(0 6px 8px rgba(0,0,0,0.12))); }
/* Keep the paper inside the drawn envelope, including its rounded corners. */
.seal-art svg > rect { fill: var(--paper-card); }
.paper:hover .paper-art { transform: rotate(0deg) translateY(-3px); }
.paper:active .paper-art { transform: translateY(1px); }
.paper:focus-visible { outline: 2px solid var(--link); outline-offset: 4px; border-radius: 8px; }
.paper-sub { display: block; font-size: 0.66rem; color: var(--rule); margin-top: 10px; }
.paper[disabled] { opacity: 0.55; pointer-events: none; }

/* the writing sheet morphs to the chosen paper. Either way it is PAPER
   LYING ON STEEL: a drawn card that casts onto the panel below it. */
.pb-sheet {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  border: 1.5px solid var(--draw-ink);
  border-radius: 8px;
  background: var(--paper-card);
  padding: 12px 14px;
  box-shadow: var(--card-cast, 0 6px 12px rgba(0, 0, 0, 0.2));
}
.postbox-form.postcard .pb-sheet {
  flex-direction: row;
  gap: 14px;
}
.postbox-form.postcard .pb-sheet textarea { flex: 1.3; }
.postbox-form.postcard .pb-side {
  flex: 0.9;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--rule-soft);
  padding-left: 14px;
}
.pb-stamp { display: none; }
.postbox-form.postcard .pb-stamp { display: block; align-self: flex-end; width: 26px; height: 31px; background: var(--acc); border: 1px solid var(--draw-ink); border-radius: 2px; }
.postbox-form.postcard .pb-side .pb-sign { margin-top: auto; }
.postbox-form.sealed .pb-side { display: contents; }
.pb-send { display: flex; align-items: center; gap: 8px; margin-left: auto; padding: 7px 16px; font: inherit; font-size: 0.78rem; font-weight: 600; cursor: pointer; color: var(--bg); background: var(--ink); border: 0; border-radius: 10px;
  /* a pressed steel plate, not a flat web button */
  box-shadow: 0 2px 5px var(--slot-cast, rgba(0, 0, 0, 0.3)), inset 0 1px 0 var(--slot-glint, rgba(255, 255, 255, 0.18)); }
.pb-send:active { transform: translateY(1px); box-shadow: 0 1px 2px var(--slot-cast, rgba(0, 0, 0, 0.3)), inset 0 1px 0 var(--slot-glint, rgba(255, 255, 255, 0.18)); }
.pb-send .wax { display: none; width: 15px; height: 15px; color: var(--wax-ink, #fff); }
.postbox-form.sealed .pb-send .wax { display: block; }

/* THE PILE IS GONE (Emil, 2026-08-30: letters on the ground "looks kinda
   disrespectful"). Its replacements: approved letters live only on the
   chain (.pb-readlink at the panel's foot opens it), and the visitor's own
   unapproved letter stays STUCK IN THE MOUTH — folded, pushed in, a part
   showing. Four poses, chosen per letter by theme.js, so two letters never
   sit identically. Each is paper folded once: the crease is a shadow line
   across the middle, the half below the crease a shade darker because it
   tips away from the light from above. */
.pk-stuck {
  position: absolute;
  z-index: 1;   /* over the plate, under #pk-peek */
  background:
    linear-gradient(180deg,
      var(--paper-card) 0 44%,
      var(--stuck-crease, rgba(0, 0, 0, 0.18)) 50%,
      var(--stuck-under, #ececea) 56% 100%);
  border: 1px solid var(--faint-ink);
  border-radius: 1px;
  box-shadow: var(--strip-cast, 0 2px 3px rgba(0, 0, 0, 0.25));
  transform-origin: 50% 0;
}
/* the poses: all hang OUT of the mouth (top tucked under its lip at 20%,
   the mouth spans 14–21.5%), differing in reach, width and tilt */
.pk-stuck.v0 { left: 16%; top: 20%; width: 42%; height: 24%; transform: rotate(-7deg); }
.pk-stuck.v1 { left: 40%; top: 20.5%; width: 38%; height: 20%; transform: rotate(4deg); }
.pk-stuck.v2 { left: 24%; top: 20%; width: 46%; height: 18%; transform: rotate(-2deg) skewX(-3deg); }
.pk-stuck.v3 { left: 44%; top: 20.5%; width: 34%; height: 26%; transform: rotate(9deg); }
@media (prefers-reduced-motion: reduce) { .paper-art { transition: none; } }

/* the way to the chain: a quiet line at the panel's foot */
.pb-readlink {
  flex: 0 0 auto;
  align-self: center;
  margin: 2px 0 0;
  padding: 2px 0;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 0.72rem;
  color: var(--rule);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pb-readlink:hover { color: var(--ink); }

.postbox-form .status { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.72rem; color: var(--rule); min-height: 1em; }

/* ---- THE CHAIN: every public letter, chronological, linked by real gold
   chain links between the cards. The chain scrolls on its own; the writing
   desk above stays put. */
.chain-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 2px 0 0;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--serif);
  font-variant: small-caps;
  font-size: 0.85rem;
}
.chain {
  overflow-y: auto;
  overscroll-behavior: contain;
  min-height: 0;
  padding: 10px 2px 4px;
}
.chain-letter {
  position: relative;
  padding: 10px 12px 8px;
  background: var(--panel);
  border: 1px solid var(--rule-soft);
  border-radius: 3px;
  /* each letter is paper lying on the steel panel */
  box-shadow: var(--card-cast, 0 4px 8px rgba(0, 0, 0, 0.16));
}
.chain-letter:nth-child(odd)  { transform: rotate(-0.35deg); }
.chain-letter:nth-child(even) { transform: rotate(0.35deg); }
/* two interlocked links of the site's gold hang between consecutive letters */
.chain-letter + .chain-letter { margin-top: 26px; }
.chain-letter + .chain-letter::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -27px;
  width: 14px;
  height: 28px;
  transform: translateX(-50%);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 28'%3E%3Cellipse cx='7' cy='8' rx='4.6' ry='7' fill='none' stroke='%23ddb05c' stroke-width='2.4'/%3E%3Cellipse cx='7' cy='20' rx='4.6' ry='7' fill='none' stroke='%23ddb05c' stroke-width='2.4'/%3E%3C/svg%3E") center / contain no-repeat;
}
.chain-letter p {
  margin: 0;
  font-family: var(--serif);
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;   /* a letter's own line breaks are the writer's */
  overflow-wrap: anywhere;
}
.chain-letter .by {
  display: block;
  margin-top: 6px;
  font-size: 0.68rem;
  color: var(--rule);
  font-variant-numeric: lining-nums tabular-nums;
}
.chain-empty { margin: 4px 0 2px; font-size: 0.74rem; color: var(--rule); }

/* ---- motion. Fast and physical: the panel rises out of the box, the chain
   letters cascade in, a sent letter flies INTO the box and the box takes the
   thunk. All of it sits behind prefers-reduced-motion. */
/* postbox-in is GONE (2026-08-30): the box's own FLIP is the entrance now,
   and a keyframe animation on the same element OVERRIDES the FLIP's inline
   transform for its whole 0.26s — the panel popped to near-full size, then
   jumped into the tail of the magnification. One motion, one owner. */
.chain-letter { animation: chain-in 0.32s cubic-bezier(0.3, 0.6, 0.2, 1) both; animation-delay: calc(var(--i, 0) * 45ms); }
@keyframes chain-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
/* chain-in ends at `none`, so the resting tilt is reapplied after it */
.chain-letter:nth-child(odd)  { animation-name: chain-in-odd; }
.chain-letter:nth-child(even) { animation-name: chain-in-even; }
@keyframes chain-in-odd  { from { opacity: 0; transform: translateY(-8px) rotate(-0.35deg); }
                           to   { opacity: 1; transform: rotate(-0.35deg); } }
@keyframes chain-in-even { from { opacity: 0; transform: translateY(-8px) rotate(0.35deg); }
                           to   { opacity: 1; transform: rotate(0.35deg); } }
/* a postcard just sent: hangs at the top of the chain, visibly not yet real */
.chain-letter.pending { border-style: dashed; background: var(--bg); }
.chain-letter.pending .by { color: var(--acc); }
/* the flown letter: a small paper the JS animates from the button to the box */
.pk-fly {
  position: fixed;
  z-index: 70;
  width: 46px;
  height: 32px;
  pointer-events: none;
  color: var(--ink);
  filter: var(--peek-cast, drop-shadow(0 3px 5px rgba(0,0,0,.25)));
}
.pk-fly svg { width: 100%; height: 100%; }
#postkasten.thunk { animation: pk-thunk 0.32s cubic-bezier(0.3, 0.6, 0.2, 1); }
@keyframes pk-thunk {
  30% { transform: translateY(3px); }
  60% { transform: translateY(-1px); }
}
/* ---- the typeform flow: ONE question at a time, each sliding up in.
   MUCH simpler content (Emil, 2026-08-28): write → public? → sign → done. */
.pb-step { display: none; }
/* the active step is a shrinkable column, so the paper sheet always fits
   the panel WITH its nav row — nothing may hang past the steel edge */
.pb-step.active { display: flex; flex-direction: column; justify-content: center; flex: 1 1 auto; min-height: 0; animation: step-in 0.34s cubic-bezier(0.3, 0.6, 0.2, 1); }
@keyframes step-in {
  from { opacity: 0; transform: translateY(26px); }
}
.pb-q {
  margin: 6px 0 12px;
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 400;
  line-height: 1.3;
  /* engraved into the steel: dark ink with the light-from-above glint
     under each stroke */
  text-shadow: 0 1px 0 var(--slot-glint, rgba(255, 255, 255, 0.45));
}
.pb-nav { display: flex; align-items: center; gap: 8px; margin-top: 4px; flex: 0 0 auto; }
.pb-nav button[type="submit"], .pb-nav .pb-again { margin-left: auto; }
.pb-back {
  padding: 4px 8px;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  color: var(--rule);
  background: none;
  border: 0;
}
.pb-back:hover { color: var(--ink); }
.pb-again {
  padding: 6px 14px;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  color: var(--bg);
  background: var(--ink);
  border: 0;
  border-radius: 3px;
}
.pb-view.pb-read { display: flex; flex-direction: column; min-height: 0; }
.pb-view[hidden] { display: none !important; }
.pb-view:not([hidden]) { animation: view-in 0.3s cubic-bezier(0.3, 0.6, 0.2, 1); }
@keyframes view-in {
  from { opacity: 0; transform: translateX(18px); }
}
.pb-backwrite {
  align-self: flex-start;
  margin: 0 0 6px;
  padding: 2px 0;
  font: inherit;
  font-size: 0.78rem;
  color: var(--rule);
  background: none;
  border: 0;
  cursor: pointer;
}
.pb-backwrite:hover { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .postbox:not([hidden]), .chain-letter, #postkasten.thunk,
  .pb-step.active, .pb-view:not([hidden]) { animation: none; }
}

/* Print the Hierarchy: garage chrome, nav, letters, crumb drop away.
   The triangle fills the sheet. Other wiki pages keep their article flow. */
@media print {
  @page { margin: 1cm; }
  html, html:has(.scene.garage), body, body.center {
    background: var(--bg) !important;
    min-height: 0 !important;
    height: auto !important;
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
  }
  #navbar, #curtain, #expand, #print, .door-tools, #postkasten, .postbox, #world, #doorlock,
  .crumb, header.masthead, .wiki-print,
  .scene.garage::before, .scene.garage::after,
  .garage .well::after, .scene .frame::before {
    display: none !important;
  }
  .scene.garage,
  .garage .well,
  .garage .well .frame,
  .frame .pane,
  .pane.wikipane,
  .pane.wikipane:has(> .wiki-poster),
  .pane.wikipane:has(> .wiki-ehh),
  .pane.wikipane main.wiki-poster,
  .pane.wikipane main.wiki-ehh,
  .frame .section {
    position: static !important;
    inset: auto !important;
    width: auto !important;
    max-width: none !important;
    height: auto !important;
    min-height: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: visible !important;
    background: transparent !important;
    box-shadow: none !important;
    display: block !important;
    flex: none !important;
    filter: none !important;
  }
  .ehh {
    display: flex !important;
    flex-direction: column !important;
    height: auto !important;
  }
  .ehh-pyramid {
    animation: none !important;
    width: 100% !important;
    height: auto !important;
    min-height: 0 !important;
    aspect-ratio: 6 / 5;
    flex: none !important;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
  .ehh-band::after { display: none !important; }
  .wiki-poster .wiki-art {
    position: static !important;
    inset: auto !important;
    display: block !important;
    width: auto !important;
    height: auto !important;
    max-width: none !important;
    padding: 0 !important;
    margin: 0 !important;
  }
  .wiki-poster .wiki-art img {
    width: 100% !important;
    height: auto !important;
    max-height: 100vh !important;
    object-fit: contain !important;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}

/* The hierarchy anchors the overview; the articles belong to its layers. */
.index-grid:has(.hierarchy-overview) { grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); }
.toc:has(.hierarchy-overview) { height: auto; overflow: visible; }
.hierarchy-overview { display: block; margin-bottom: 24px; }
.hierarchy-caption { display: block; margin-top: 12px; font-family: var(--serif); font-size: .75rem; font-style: italic; font-weight: 400; text-align: center; }
.index-grid:has(.hierarchy-overview) .index-head { height: auto; }
@media (max-width: 649px) {
 .index-grid:has(.hierarchy-overview) { grid-template-columns: minmax(0, 1fr); }
 .hierarchy-overview { max-width: 320px; margin-inline: auto; }
}

/* Miniature uses the article's own bands and icons, within the grey rail. */
.ehh.ehh-mini { height: auto; min-height: 0; container-type: inline-size; }
.ehh-mini .ehh-pyramid { position: relative; bottom: auto; left: auto; transform: none; width: 100%; aspect-ratio: 1.1; margin: 0; padding: 0; }
.toc .ehh-mini li { margin: 0; }
.ehh-mini .ehh-name { font-size: calc(2.9cqw + var(--ehh-rank) * .4cqw); }
.ehh-mini .ehh-band[data-band="surroundings"] .ehh-name { font-size: 2.5cqw; }
.hierarchy-overview:focus-visible { outline: 2px solid var(--ink); outline-offset: 5px; }

/* Wiki: the foundations become navigation, in reading order. */
.wiki-orientation { display:grid; grid-template-columns:minmax(190px, 260px) minmax(0,1fr); gap:40px; align-items:start; }
.foundation-menu.ehh { height:max(540px, calc(var(--pane-h, 100vh) - 90px)); min-height:0; container-type:normal; display:flex; flex-direction:column; gap:6px; padding:18px; background:var(--grain) 0 0 / 160px 160px, var(--panel); background-blend-mode:soft-light, normal; border:1px solid var(--rule-soft); }
.foundation { --layer-color:var(--ehh-attention); display:flex; flex:1; align-items:center; gap:18px; min-height:72px; width:100%; border:0; border-left:0; padding:18px 16px; background:color-mix(in srgb, var(--layer-color) 64%, var(--panel)); color:var(--ehh-ink); cursor:pointer; text-align:left; transition:background-color .18s ease; }
.foundation[data-layer="people"] { --layer-color:var(--ehh-people); }
.foundation[data-layer="sleep"] { --layer-color:var(--ehh-sleep); }
.foundation[data-layer="movement"] { --layer-color:var(--ehh-movement); }
.foundation[data-layer="nutrition"] { --layer-color:var(--ehh-nutrition); }
.foundation[data-layer="surroundings"] { --layer-color:var(--ehh-surroundings); }
.foundation[data-layer="attention"]:is(:hover,[aria-pressed="true"]) { color:var(--ehh-on-deep); }
.foundation:hover,.foundation[aria-pressed="true"] { background:var(--layer-color); }
.foundation[data-layer="attention"]:hover { background:color-mix(in srgb,var(--ehh-attention),var(--ehh-ink) 12%); }
.foundation:focus-visible { outline:2px solid var(--ink); outline-offset:-4px; }
.foundation .ehh-mark { position:static; transform:none; width:25px; height:27px; flex:none; }
.foundation .ehh-copy { position:static; display:block; }
.foundation .ehh-name { font-size:17px; line-height:1.3; font-family:var(--serif); font-weight:400; }
.foundation[aria-pressed="true"] .ehh-name { font-weight:700; }
.wiki-intro { display:flow-root; padding:8px 0 clamp(140px, 18vh, 210px); }
.wiki-recent h2 { margin:0 0 18px; font-size:1rem; font-weight:400; }
.wiki-recent [hidden] { display:none !important; }
@media(max-width:649px) {
 .wiki-orientation { grid-template-columns:minmax(0,1fr); gap:24px; }
 .foundation-menu.ehh { height:auto; display:grid; grid-template-columns:1fr 1fr; padding:14px; }
 .wiki-intro { padding-bottom:90px; }
 .foundation { min-height:66px; padding:12px 10px; gap:8px; }
 .foundation .ehh-name { font-size:15px; }
}
@media(prefers-reduced-motion:reduce) { .foundation { transition:none; } }

/* A quiet frontispiece above the foundations, with air between the bands. */
.foundation-menu.ehh { height:min(520px, calc(var(--pane-h, 100vh) - 64px)); min-height:0; gap:14px; }
.foundation-stack { display:flex; flex:1; min-height:0; flex-direction:column; gap:12px; }
.wiki-home { display:flex; flex-direction:column; align-items:center; gap:5px; padding:0 0 12px; border:0; border-bottom:1px solid var(--rule-soft); background:transparent; color:var(--ink); font:14px var(--serif); cursor:pointer; }
.wiki-home svg { width:72px; height:38px; }
.wiki-home:hover span { text-decoration:underline; }
.wiki-home:focus-visible { outline:2px solid var(--ink); outline-offset:3px; }
.wiki-orientation[data-filtered="true"] .wiki-intro { display:none; }
.wiki-orientation[data-filtered="true"] .wiki-recent { padding-top:8px; }
.wiki-recent .doc-text { min-width:0; }
.wiki-recent .doc-title,.wiki-recent .doc-sum { display:block; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.wiki-recent .doc-meta { display:flex; align-items:center; gap:12px; margin-top:7px; white-space:nowrap; }
.article-tag { --tag-color:var(--ehh-movement, #e6a83d); background:color-mix(in srgb,var(--tag-color) 64%,var(--panel)); color:var(--ink); padding:1px 7px; font:11px/1.5 var(--serif); border-left:0; }
.article-tag[data-tag="attention"] { --tag-color:var(--ehh-attention, #a92323); }
.article-tag[data-tag="sleep"] { --tag-color:var(--ehh-sleep, #e68536); }
.article-tag[data-tag="people"] { --tag-color:var(--ehh-people, #e05d2d); }
.article-tag[data-tag="nutrition"] { --tag-color:var(--ehh-nutrition, #99ac7d); }
.article-tag[data-tag="surroundings"] { --tag-color:var(--ehh-surroundings, #5e8b84); }
@media(max-width:649px) {
 .foundation-menu.ehh { min-height:0; display:flex; }
 .foundation-stack { display:grid; grid-template-columns:1fr 1fr; gap:12px; }
 .wiki-home { flex-direction:row; justify-content:center; padding:0 0 16px; }
 .wiki-home svg { width:60px; height:34px; }
}

@media(min-width:650px) {
 .foundation-menu.ehh { padding:14px 18px; }
 .foundation { min-height:36px; padding:6px 16px; }
 .foundation .ehh-mark { width:22px; height:23px; }
}
@media(max-width:649px) { .foundation-menu.ehh { height:auto; } }

.foundation .ehh-mark { color:var(--ehh-on-deep); }
.wiki-intro-art { margin:0 auto 32px; width:180px; max-width:50%; color:var(--ink); }
.wiki-intro-art svg { display:block; width:100%; height:160px; }
@media(max-width:649px) { .wiki-intro-art { margin-bottom:24px; } .wiki-intro-art svg { height:130px; } }

/* The home is one composed page; category lists scroll inside their region. */
.pane.wikipane:has(.wiki-orientation) { overflow:hidden; }
.pane.wikipane main.index-page:has(.wiki-orientation) { height:100%; padding:22px 32px; box-sizing:border-box; }
.wiki-orientation { height:100%; min-height:0; }
.foundation-menu.ehh { height:100%; min-height:0; }
.wiki-reading { height:100%; min-height:0; display:grid; grid-template-rows:minmax(0,1fr) auto; gap:18px; }
.wiki-intro { min-height:0; padding:0; display:flex; flex-direction:column; gap:10px; }
.wiki-intro-art { flex:1; min-height:40px; width:100%; max-width:none; margin:0; }
.wiki-intro-art svg { height:100%; width:100%; max-height:230px; }
.wiki-intro .lede { font-size:clamp(15px,1.3vw,19px); line-height:1.5; margin:0; }
.wiki-recent { min-height:0; padding:12px 16px; border:1px solid var(--rule-soft); background:var(--panel); }
.wiki-recent h2 { margin:0 0 8px; font-size:.85rem; }
.wiki-recent .docs { margin:0; padding:0; }
.wiki-recent .docs li { margin:0; }
.wiki-recent .doc { padding:7px 0; }
.wiki-recent .doc-title { font-size:16px; line-height:1.25; }
.wiki-recent .doc-sum { font-size:13px; line-height:1.3; }
.wiki-recent .doc-meta { margin-top:3px; font-size:11px; line-height:1.4; }
.wiki-orientation[data-filtered="true"] .wiki-reading { grid-template-rows:minmax(0,1fr); }
.wiki-orientation[data-filtered="true"] .wiki-recent { overflow-y:auto; }
.tree-branch { animation:wiki-breeze 12s ease-in-out infinite; animation-delay:var(--delay); }
.tree-leaf { animation:wiki-leaf 7s ease-in-out infinite; animation-delay:var(--delay); }
@keyframes wiki-breeze { 0%,100%{transform:rotate(-.4deg)}50%{transform:rotate(.6deg)} }
@keyframes wiki-leaf { 0%,100%{transform:rotate(-2deg)}50%{transform:rotate(3deg)} }
@media(max-width:649px) {
 .pane.wikipane main.index-page:has(.wiki-orientation) { padding:12px 16px; }
 .wiki-orientation { grid-template-rows:auto minmax(0,1fr); gap:12px; }
 .foundation-menu.ehh { padding:8px; gap:8px; }
 .foundation-stack { gap:6px; }
 .foundation { min-height:30px; padding:4px 10px; }
 .foundation .ehh-mark { width:18px; height:20px; }
 .wiki-home { padding:0 0 6px; gap:8px; }
 .wiki-home svg { height:22px; width:40px; }
 .wiki-reading { gap:10px; }
 .wiki-intro .lede { font-size:14px; line-height:1.35; }
 .wiki-recent { padding:8px 12px; }
}
@media(prefers-reduced-motion:reduce) { .tree-branch,.tree-leaf { animation:none; } }

.wiki-intro-art { position:relative; }
.wiki-intro-art svg { position:absolute; inset:0; max-height:none; }

.wiki-intro .lede { display:flow-root; flex:none; }

/* Keep the growing canopy compact, including its wind movement. */
.wiki-reading,.wiki-intro { min-width:0; }
.wiki-intro-art { overflow:hidden; }
.wiki-intro-art svg { left:50%; right:auto; width:min(100%, 260px); height:100%; max-height:150px; top:50%; transform:translate(-50%,-50%); }
@media(max-width:649px) { .wiki-intro-art svg { width:min(100%, 210px); max-height:120px; } }
.wiki-reading { grid-template-columns:minmax(0,1fr); }
.wiki-recent { min-width:0; }

/* Upper artwork, mid-page prose, and two evenly spaced Latest rows. */
.wiki-intro { justify-content:flex-start; gap:14px; }
.wiki-intro-art { flex:0 1 130px; }
.wiki-intro-art svg { top:0; transform:translateX(-50%); }
.wiki-recent .docs { grid-template-columns:minmax(0,1fr); gap:0; }
.wiki-recent .docs li { min-width:0; }
.wiki-recent .docs li + li { border-top:1px solid var(--rule-soft); }
.wiki-recent .doc { padding:9px 0; }
.wiki-recent .doc-text { gap:3px; }
.wiki-recent .doc-meta { margin-top:2px; line-height:1.5; }
.wiki-recent .article-tag { line-height:1.3; }
@media(max-width:649px) {
 .wiki-intro { gap:10px; }
 .wiki-intro-art { flex-basis:90px; }
 .wiki-recent .doc { padding:7px 0; }
}
