/* THE VALLEY — luyml.com static rebuild, 2026-07-31.
   One world, one physics (WORLDBUILDING_JITSU): every value on the scales below.
   Colour law: the sky is the foundation, EPA AQI tones are the only data colour,
   amber is the one sun accent. Ink is the sky's own hue, set by the engine. */

@font-face { font-family: 'Fraunces'; src: url('/fonts/fraunces-var.woff2') format('woff2'); font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'Poppins'; src: url('/fonts/poppins-400.woff2') format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Poppins'; src: url('/fonts/poppins-500.woff2') format('woff2'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'Poppins'; src: url('/fonts/poppins-600.woff2') format('woff2'); font-weight: 600; font-display: swap; }

:root {
  /* the engine writes these at runtime; defaults are the night valley.
     --ink/--sky theme the SKY zone (threshold); --lnk/--land theme the LAND,
     the solid reading surface below the horizon line. */
  --ink: 236 238 246;
  --sky: 14 20 42;
  --lnk: 233 236 244;
  --land: 24 28 44;
  --sun: 199 137 58;               /* the one warm accent (luyml-color-law) */
  --disp: 'Fraunces', 'Times New Roman', serif;
  --body: 'Poppins', system-ui, sans-serif;
  /* solid ink tiers mixed against the page's own colour — never alpha over gradient */
  /* tiers stay within 7:1 of the sky's extremes (measured; the engine drives
     ink-1 to 8.5:1 so these mixes keep the floor). Hierarchy leans on size and
     weight, not on washing the ink out. */
  --ink-1: rgb(var(--ink));
  --ink-2: color-mix(in srgb, rgb(var(--ink)) 92%, rgb(var(--sky)));
  --ink-3: color-mix(in srgb, rgb(var(--ink)) 90%, rgb(var(--sky)));
  --rule-1: color-mix(in srgb, rgb(var(--ink)) 34%, rgb(var(--sky)));
  --rule-2: color-mix(in srgb, rgb(var(--ink)) 18%, rgb(var(--sky)));
  /* the scales — the world's only sizes */
  --s1: 8px; --s2: 14px; --s3: 22px; --s4: 36px; --s5: 58px; --s6: 94px;
  --measure: 1180px;
  --ease: cubic-bezier(.22, .8, .3, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
html, body { overflow-x: clip; }
body {
  font-family: var(--body); color: var(--ink-1);
  background: rgb(var(--sky));
  -webkit-font-smoothing: antialiased;
  line-height: 1.5; font-size: 16px;
}
/* the sky itself — fixed, painted by the engine */
.sky { position: fixed; inset: 0; z-index: -2; background: linear-gradient(180deg, #0e142a, #1a2246); transition: background 2.4s linear; }
/* film grain, one tiled data-URI, whisper-quiet */
.grain { position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: .05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E"); }

a { color: inherit; }
::selection { background: rgb(var(--sun) / .45); }
:focus-visible { outline: 2px solid rgb(var(--sun)); outline-offset: 3px; }

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 var(--s3); }

/* THE LAND ZONE: everything below the horizon stands on solid ground. The
   tiers are RE-DECLARED here (not just re-pointed): browsers resolve var()
   inside custom properties eagerly at the declaring element, so the :root
   tier values are baked against the sky — the land must derive its own. */
.land, .foreland, .under, .down {
  --ink: var(--lnk); --sky: var(--land);
  --ink-1: rgb(var(--lnk));
  --ink-2: color-mix(in srgb, rgb(var(--lnk)) 92%, rgb(var(--land)));
  --ink-3: color-mix(in srgb, rgb(var(--lnk)) 90%, rgb(var(--land)));
  --rule-1: color-mix(in srgb, rgb(var(--lnk)) 34%, rgb(var(--land)));
  --rule-2: color-mix(in srgb, rgb(var(--lnk)) 18%, rgb(var(--land)));
}
.land { background: rgb(var(--land)); color: var(--ink-1); transition: background 2.4s linear; position: relative; z-index: 1; }

/* ── the masthead ── */
.masthead { position: absolute; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; justify-content: space-between; align-items: baseline;
  padding: var(--s3); font-size: 13px; }
.masthead .brand { font-weight: 600; letter-spacing: .16em; text-transform: uppercase; text-decoration: none; }
.masthead .dateline { color: var(--ink-2); font-weight: 500; font-variant-numeric: tabular-nums; }

/* ── the threshold: sky, the word, the horizon ── */
.threshold { position: relative; min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: flex-end; }
.word {
  font-family: var(--disp); font-weight: 560; letter-spacing: -.015em;
  font-size: clamp(60px, 12vw, 186px); line-height: .94;
  text-align: center; position: relative; z-index: 2; margin-bottom: -0.115em;
  padding: 0 var(--s3);
}
/* the period is lit by the sun: amber while it is up, quiet ink after it sets */
.word .dot { color: rgb(var(--sun)); }
body.sundown .word .dot { color: var(--ink-3); }
.horizon { display: block; width: 100%; height: auto; position: relative; z-index: 1; margin-top: clamp(-120px, -7vw, 0px); }
/* the sun: a luminous disc whose bloom sits exactly on the sky-glow's position */
.sundisc { position: absolute; z-index: 1; width: 190px; height: 190px; border-radius: 50%;
  transform: translate(-50%, -50%); pointer-events: none; opacity: 0; transition: opacity 2.4s linear;
  background: radial-gradient(circle,
    rgb(255 247 228) 0%, rgb(255 236 196) 7%, rgb(250 200 124 / .55) 13%,
    rgb(240 178 100 / .28) 30%, rgb(240 178 100 / 0) 68%); }
.horizon .terrain { stroke: color-mix(in srgb, rgb(var(--lnk)) 60%, rgb(var(--land))); fill: none; }
.horizon .ground { fill: rgb(var(--land)); transition: fill 2.4s linear; }
.horizon .arc { stroke: var(--ink-3); }
.horizon .h-label { font: 500 11px var(--body); letter-spacing: .04em;
  fill: color-mix(in srgb, rgb(var(--lnk)) 90%, rgb(var(--land))); }
/* the live line stands ON the land, data at the left rail, the region's line at the right */
.under {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); flex-wrap: wrap;
  padding: 0 var(--s3) var(--s4); margin-top: calc(-1 * var(--s2));
  font-size: 13.5px; color: var(--ink-2); font-weight: 500;
  position: relative; z-index: 2; max-width: var(--measure); margin-left: auto; margin-right: auto; width: 100%;
}
/* the strip of land between the horizon drawing and the fold */
.foreland { --ink: var(--lnk); --sky: var(--land);
  background: rgb(var(--land)); transition: background 2.4s linear;
  position: relative; z-index: 2; margin-top: -1px; }
.under-data { display: inline-flex; gap: var(--s3); }
.under .dot-live { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; background: var(--rule-1); }
.under .quiet { color: var(--ink-3); }
.down { display: block; width: fit-content; margin: calc(-1 * var(--s3)) auto var(--s2);
  color: var(--ink-3); font-size: 18px; text-decoration: none; }

/* ── entrances: gentle, once, honored ── */
.enter { animation: enter .7s var(--ease) backwards; }
.enter.d1 { animation-delay: .08s; } .enter.d2 { animation-delay: .16s; } .enter.d3 { animation-delay: .26s; }
@keyframes enter { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

/* ── the doors: places in the valley ── */
.section { padding: var(--s6) 0 var(--s5); }
.kicker { font-size: 12px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s2); }

/* the pictures start where the sky ends: no landing strip of empty land above them */
.has-collage.section { padding-top: var(--s3); }
.has-collage .kicker { margin-bottom: var(--s2); }

/* ── THE COLLAGE (desktop): the worlds as a randomized diagonal split-screen —
   every panel a real page, hover lights it live. Built by JS as enhancement;
   the door rows below remain the no-JS/phone navigation (honesty law M1). ── */
.collage { position: relative; width: 100%; height: clamp(420px, 58vh, 640px);
  border-radius: 14px; overflow: hidden; }
.cpanel { position: absolute; inset: 0; display: block;
  clip-path: polygon(var(--x1) 0, var(--x2) 0, var(--x3) 100%, var(--x4) 100%);
  transition: clip-path .5s var(--ease); text-decoration: none; }
/* every slice shows ITS page's own centre column (shot and live iframe both
   register on --cx): the random cut changes the rhythm, never the subject —
   a slice that lands on a page's empty margin is a dead panel */
.cpanel img.shot { position: absolute; top: 0; left: var(--cx); height: 100%; width: auto;
  transform: translateX(calc(var(--fx, .5) * -100%));
  filter: saturate(.9) brightness(.82); transition: filter .45s; }
.cpanel .tone { position: absolute; inset: 0; background: rgb(var(--sky));
  mix-blend-mode: soft-light; opacity: .25; pointer-events: none; transition: opacity .45s; }
.cpanel iframe { position: absolute; top: 50%; width: 1200px; height: 760px; border: 0;
  transform: translate(calc(var(--fx, .5) * -100%), -50%) scale(var(--fs, 0.9));
  opacity: 0; transition: opacity .5s;
  pointer-events: none; z-index: 1; }
.cpanel iframe.live { opacity: 1; }
.cpanel:hover img.shot, .cpanel:focus-visible img.shot { filter: saturate(1) brightness(1) contrast(1); }
.cpanel:hover .tone, .cpanel:focus-visible .tone { opacity: 0; }
/* the name chip sits on the panel's BOTTOM edge midpoint (the clip-path cuts
   children, so the chip must live inside its own slice); a slim slice wears
   the emblem alone and reveals its name as the hover widens it */
.cpanel .tag { position: absolute; bottom: 16px; left: calc((var(--x3) + var(--x4)) / 2);
  z-index: 2; /* the name outranks the live window it names */
  transform: translateX(-50%); display: flex; align-items: center; gap: 7px; white-space: nowrap;
  background: color-mix(in srgb, rgb(var(--land)) 92%, transparent);
  color: var(--ink-1); border: 1px solid var(--rule-1); border-radius: 999px;
  padding: 6px 13px 6px 10px; font: 500 12.5px var(--body); backdrop-filter: blur(5px); }
.cpanel .tag svg { width: 16px; height: 16px; display: block; }
.cpanel.slim .tag { padding: 6px 8px; }
.cpanel.slim .tag > span { display: none; }
.cpanel.flat { background: color-mix(in srgb, rgb(var(--lnk)) 8%, rgb(var(--land))); }
.cpanel.flat .big-mark { position: absolute; top: 44%; left: var(--cx); transform: translate(-50%, -50%);
  color: var(--ink-3); display: flex; flex-direction: column; align-items: center; gap: 12px; }
.cpanel.flat .big-mark svg { width: 44px; height: 44px; }
.cpanel.flat .big-mark span { writing-mode: vertical-rl; font: 500 11px var(--body);
  letter-spacing: .08em; white-space: nowrap; }
.cpanel:focus-visible { outline: none; }
.has-collage .doors { display: none; }
@media (max-width: 799.9px) { .collage { display: none; } }
@media (prefers-reduced-motion: reduce) { .cpanel { transition: none; } }

/* ── THE WALL (phone): the places as pictures, two to a row, right under the fold.
   The reference walls (a feed of pictures, a wall of art, a grid of thumbnails)
   carry the thing in the picture and put the name on it; nothing is a list.
   A tap on a tile walks in. The small LOOK control on a tile opens the place
   LIVE, in place, full width; nothing loads a live site until a person asks
   (2026-09-04: five live sites were loading themselves on scroll). ── */
.wall { display: none; }
@media (max-width: 799.9px) {
  .has-collage .doors { display: none; }
  .wall { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 calc(-1 * var(--s3)); padding: 0 var(--s3) var(--s3); }
  .tile { position: relative; display: block; aspect-ratio: 4 / 5; border-radius: 14px; overflow: hidden;
    background: color-mix(in srgb, rgb(var(--lnk)) 10%, rgb(var(--land))); }
  .tile .go { position: absolute; inset: 0; display: block; text-decoration: none; }
  .tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
  .tile::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 46%; pointer-events: none;
    background: linear-gradient(rgb(0 0 0 / 0), rgb(0 0 0 / .55)); }
  .tile .tag { position: absolute; left: 10px; right: 10px; bottom: 10px; z-index: 2; display: flex; align-items: center; gap: 7px;
    color: #fff; font: 600 15px/1.2 var(--body); text-shadow: 0 1px 2px rgb(0 0 0 / .5); }
  .tile .tag svg { width: 18px; height: 18px; flex: none; filter: drop-shadow(0 1px 1px rgb(0 0 0 / .5)); }
  .tile .tag .live { margin-left: auto; font: 600 12px var(--body); white-space: nowrap; }
  /* The LOOK control is the one control on a picture, and a control's boundary must be seen
     against whatever it sits on (WCAG 1.4.11, 3:1). Land at 86% over a bright day photograph
     measured 2.37:1 on every tile at 390, 2026-09-09. So: an opaque land disc with a ring in
     the page's own ink at the standard's line width, 1.5px; the ink follows the hour, deep by
     day and luminous by night, so the ring is seen on any photograph at any hour. */
  .tile .look { position: absolute; top: 8px; right: 8px; z-index: 3; width: 44px; height: 44px; border-radius: 50%;
    display: grid; place-items: center; border: 1.5px solid var(--ink-1); padding: 0; cursor: pointer;
    background: rgb(var(--land)); color: var(--ink-1); }
  .tile .look svg { width: 20px; height: 20px; }
  .tile .enter-bar, .tile iframe { display: none; }
  /* open: the tile takes the row, the live page stands in it, the door is a bar in the thumb's third */
  .tile.open { grid-column: 1 / -1; aspect-ratio: auto; height: 78svh; min-height: 460px; }
  .tile.open img { filter: saturate(.5) brightness(.6); }
  .tile.open iframe { display: block; position: absolute; top: 0; left: 50%; width: 390px; height: 844px;
    transform: translateX(-50%) scale(var(--ms, 1)); transform-origin: top center; border: 0; z-index: 1;
    opacity: 0; transition: opacity .5s; pointer-events: none; }
  .tile.open iframe.live { opacity: 1; }
  .tile.open .tag { display: none; }
  .tile.open .go { z-index: 0; }
  .tile.open .enter-bar { display: flex; position: absolute; left: var(--s2); right: var(--s2); bottom: var(--s2); z-index: 2;
    align-items: center; justify-content: center; gap: 8px; min-height: 52px;
    background: rgb(var(--land)); color: var(--ink-1); border: 1.5px solid var(--rule-1); border-radius: 13px;
    font: 600 14.5px var(--body); text-decoration: none; }
  .tile.open::after { height: 30%; background: linear-gradient(rgb(var(--land) / 0), rgb(var(--land))); z-index: 1; }
}

/* A place that is not built yet is not a door, so it wears neither a door's tile on the phone nor a
   door's sliver in the collage: a grey shape like the pressable ones is a signifier for something
   you cannot press (NNG 2017, weak and false signifiers cost fixations). The unbuilt places are one
   line of text under the wall or the collage, with their marks, and nothing to tap. */
.wall-soon { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  padding: 10px 2px 0; color: var(--ink-3); font: 500 13px/1.4 var(--body); }
.wall-soon span { display: inline-flex; align-items: center; gap: 6px; }
.wall-soon svg { width: 18px; height: 18px; opacity: .8; }

.doors { border-top: 1px solid var(--rule-2); }
/* fixed column widths so every row shares the same left edges (grid discipline:
   the fr columns must not resize per-row around the variable host width) */
.door {
  display: grid; grid-template-columns: 26px 30px clamp(160px, 22vw, 260px) minmax(0, 1fr) clamp(150px, 20vw, 240px); gap: var(--s3);
  align-items: baseline; padding: var(--s3) var(--s1);
  border-bottom: 1px solid var(--rule-2); text-decoration: none;
  transition: background .3s var(--ease);
}
.door-host { text-align: right; }
a.door:hover, a.door:focus-visible { background: color-mix(in srgb, rgb(var(--ink)) 5%, transparent); }
.lamp { width: 10px; height: 10px; border-radius: 50%; justify-self: center; align-self: center;
  background: rgb(var(--sun)); box-shadow: 0 0 12px 2px rgb(var(--sun) / .55); }
a.door:hover .lamp, a.door:focus-visible .lamp { box-shadow: 0 0 22px 6px rgb(var(--sun) / .8); }
.door.unlit .lamp { background: transparent; border: 1px solid var(--rule-1); box-shadow: none; }
.door-name { font-family: var(--disp); font-weight: 520; font-size: clamp(22px, 2.6vw, 31px); line-height: 1.15; }
.door-role { color: var(--ink-2); font-size: 14.5px; }
.door-host { color: var(--ink-3); font-size: 13px; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
a.door:hover .door-host, a.door:focus-visible .door-host { color: var(--ink-1); }
.door.unlit { color: var(--ink-3); }
.door.unlit .door-name { color: var(--ink-3); }
.door-signal-live { font-weight: 600; }

/* ── the plates: living instruments ── */
.plate { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--s4); align-items: end; padding: var(--s5) 0; }
.plate.flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.plate-no { font-size: 12px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s1); }
.plate-title { font-family: var(--disp); font-weight: 500; font-size: clamp(26px, 3.4vw, 38px); margin-bottom: var(--s3); }
.instrument { padding: var(--s2) 0; border-bottom: 1px solid var(--rule-2); }
.instrument-label { font-size: 13px; color: var(--ink-2); font-weight: 500; }
.instrument-value { font-family: var(--disp); font-weight: 500; font-size: 34px; font-variant-numeric: tabular-nums; line-height: 1.25; }
.instrument-unit { font-family: var(--body); font-size: 14px; color: var(--ink-2); font-weight: 500; }
.instrument-note { font-size: 12.5px; color: var(--ink-3); padding-top: var(--s2); }
.city-row { display: flex; align-items: baseline; gap: var(--s2); padding: 9px 0; border-bottom: 1px solid var(--rule-2); font-size: 15px; }
.city-name { font-weight: 500; }
.city-fill { flex: 1; border-bottom: 1px dotted var(--rule-1); transform: translateY(-4px); }
.city-aqi { font-weight: 600; font-variant-numeric: tabular-nums; }
.bdot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 7px; }
.city-temp { color: var(--ink-2); font-variant-numeric: tabular-nums; min-width: 3ch; text-align: right; }
.ph { position: relative; display: block; overflow: hidden; }
.ph img { width: 100%; height: auto; display: block; filter: saturate(.58) contrast(1.04); }
.photo-tone { position: absolute; inset: 0; background: rgb(var(--sky)); mix-blend-mode: soft-light; opacity: .68; pointer-events: none; }
.plate-caption { display: flex; justify-content: space-between; gap: var(--s2); flex-wrap: wrap; padding-top: var(--s1); font-size: 12.5px; color: var(--ink-3); }
.photo-credit { color: var(--ink-3); }

/* ── the statement + imprint ── */
.statement { text-align: center; padding: var(--s6) var(--s3); }
.statement h2 { font-family: var(--disp); font-weight: 540; font-size: clamp(34px, 5.4vw, 62px); line-height: 1.06; }
.statement p { color: var(--ink-2); margin-top: var(--s2); font-size: 15px; }
.imprint { border-top: 1px solid var(--rule-2); padding: var(--s4) 0 var(--s5); display: flex; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; font-size: 13px; color: var(--ink-2); }
.imprint a { color: var(--ink-2); }
.imprint .fine { color: var(--ink-3); max-width: 52ch; line-height: 1.7; }

/* ── the worldmark (picker chip, previews, the warp) wears the hour's land ── */
#worldmark {
  --wm-ink: rgb(var(--lnk));
  --wm-field: color-mix(in srgb, rgb(var(--land)) 86%, transparent);
  --wm-field-solid: rgb(var(--land));
  --wm-line: color-mix(in srgb, rgb(var(--lnk)) 34%, rgb(var(--land)));
}
.door-mark { align-self: center; }
.door-mark svg { width: 24px; height: 24px; display: block; }
.door.unlit .door-mark { opacity: .6; }

/* ── small valley (phone) ── */
@media (max-width: 800px) {
  .horizon .h-label { display: none; }
  .door { grid-template-columns: 20px 26px minmax(0, 1fr); grid-template-rows: auto auto; row-gap: 4px; }
  .door .lamp { grid-row: 1; align-self: center; }
  .door-mark { grid-row: 1; }
  .door-name { grid-column: 3; }
  .door-role { grid-column: 3; }
  .door-host { grid-column: 3; text-align: left; }
  .plate, .plate.flip { grid-template-columns: 1fr; gap: var(--s3); }
  .masthead { font-size: 11.5px; }
  .under { gap: var(--s2); font-size: 12.5px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .enter { animation: none; }
  .veil.travelling { transition: none; }
  .sky { transition: none; }
}
