/* Known, log version: the "Lattice" reface (2026-09-30).
   Layout unchanged from the soft version (kept in versions/soft/). The surface
   follows a p5.js GIF by M:PY that Josie sent: a black field, bone rounded
   squares turning on a thin grid with dots at the crossings, and prismatic
   fringes on whatever moves. lattice.js draws the moving parts under the page.
   Dark is the default; the theme button flips to a bone page.
   Type: Inter for reading, the system mono for small labels (plotted feel).
   The colours here replace the blue / vermilion / magenta rule for this
   version; the vermilion survives behind the headshot. */

:root {
  --bg: #050505;
  --fg: #F3EEE4;
  --muted: #8E8A82;
  --line: #262626;
  --card: #0B0B0B;
  --hover: rgba(243, 238, 228, .06);
  --link: var(--fg);

  /* Lattice (lattice.js reads these) */
  --grid: #1E1E1E;
  --node: #F3EEE4;
  --node-alpha: .5;
  --sq: #F3EEE4;
  --sq-alpha: 1;
  --cell: 72;
  --prism-r: #FF3B30;
  --prism-y: #FFD60A;
  --prism-c: #34E2FF;
  --prism-b: #2F6BFF;

  /* Aliases so the soft-era tokens that motion.css (the entry previews from
     the parallel session) still names degrade to flat surfaces here */
  --glass-bg: var(--card);
  --glass-edge: var(--line);
  --glass-hi: transparent;
  --glass-blur: 0px;
  --box: var(--card);
  --sh-dark: transparent;
  --sh-light: transparent;
  --raised: none;
  --raised-sm: none;
  --pressed: none;
  --pressed-sm: none;

  /* Legacy pigments: the headshot ground, the case-study viewer */
  --blue: #1B34F0;
  --verm: #CE280A;
  --mag: #B4009C;
  --ink: #000;

  --sans: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --display: Archivo, var(--sans);
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --side: 240px;
  --col: 600px;
}
:root[data-theme="light"] {
  /* white page (Josie, 2026-09-30: "this background needs to be white as well", matching the home page) */
  --bg: #FFFFFF;
  --fg: #0A0A0A;
  --muted: #5C5C5C;
  --line: #E4E4E4;
  --card: #FAFAFA;
  --hover: rgba(10, 10, 10, .06);
  --grid: #E9E9E9;
  --node: #0A0A0A;
  --node-alpha: .35;
  --sq: #0A0A0A;
  --sq-alpha: .9;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; } /* no background here: with one, the body's would stop propagating and would paint over the fixed canvas */
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 16px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}
#lattice { position: fixed; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none; }
a { color: var(--link); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: var(--muted); }
a:hover { text-decoration-color: currentColor; }
img { display: block; max-width: 100%; height: auto; }
p { margin: 0 0 12px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.frost { } /* kept for old markup; the glass overlay is gone */

/* ---------- Sidebar ---------- */
.side {
  position: fixed; left: 0; top: 0; bottom: 0;
  width: var(--side);
  padding: 22px 12px 22px 18px;
  display: flex; flex-direction: column; gap: 16px;
  font-size: 14px;
  overflow-y: auto;
}
.who { display: flex; align-items: center; gap: 12px; }
.who b { font-weight: 600; font-size: 14px; }
.ava { position: relative; display: block; flex: none; width: 48px; height: 48px; }
.ava img {
  position: absolute; inset: 4px; width: 40px; height: 40px; object-fit: cover;
  border-radius: 9px; border: 1px solid var(--line);
}
.ava svg { width: 100%; height: 100%; display: block; overflow: visible; }

.tree-toggle { display: none; }
.tree-head {
  font: 500 10px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
  margin: 6px 0 -6px 4px;
}

/* Tree rows */
.tree, .tree ul { list-style: none; margin: 0; padding: 0; }
.tree .row {
  display: flex; align-items: center; gap: 8px;
  width: 100%; height: 32px; padding: 0 8px 0 4px;
  font: inherit; color: var(--muted); text-align: left; text-decoration: none;
  background: none; border: 0; border-radius: 6px; cursor: pointer;
  white-space: nowrap; overflow: hidden;
  transition: color .15s, background-color .15s;
}
.tree .row .lbl { overflow: hidden; text-overflow: ellipsis; }
.tree .row:hover { color: var(--fg); background: var(--hover); }
.tree .row.sel { color: var(--fg); background: var(--hover); }
.tree .row.sel .lbl { font-weight: 500; }

/* Twisty: a small chevron that turns when the folder is open */
.tree .tw { flex: none; width: 14px; height: 14px; display: grid; place-items: center; }
.tree .tw .ic { width: 12px; height: 12px; transition: transform .2s; }
.tree .folder.open > .row .tw .ic { transform: rotate(90deg); }
.tree .folder > ul { display: none; }
.tree .folder.open > ul { display: block; }

/* Icons: the lattice motif. A file is one rounded square; a folder is four.
   They turn 45 degrees on hover, when selected, and when the folder is open,
   the way the squares in the GIF turn. */
.tree .ic { flex: none; width: 16px; height: 16px; overflow: visible; }
.tree .sq { fill: currentColor; transform-origin: center; transform-box: fill-box; transition: transform .45s cubic-bezier(.65, 0, .2, 1); }
.tree .row:hover .sq, .tree .row.sel .sq, .tree .folder.open > .row .sq { transform: rotate(45deg); }
.tree .ln { fill: none; stroke: var(--bg); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }

/* Connector lines: thin, like the grid */
.tree ul[role="group"] { position: relative; padding-left: 22px; }
.tree ul[role="group"] > li { position: relative; }
.tree ul[role="group"] > li::before { content: ""; position: absolute; left: -11px; top: 0; bottom: 0; width: 1px; background: var(--line); }
.tree ul[role="group"] > li:last-child::before { bottom: auto; height: 16px; }
.tree ul[role="group"] > li::after { content: ""; position: absolute; left: -11px; top: 16px; width: 12px; height: 1px; background: var(--line); }

.theme {
  margin-top: auto;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid var(--line); background: var(--bg); color: var(--fg); cursor: pointer;
  display: grid; place-items: center; border-radius: 8px;
  transition: border-color .15s;
}
.theme:hover { border-color: var(--fg); }
.theme svg { width: 15px; height: 15px; }
.theme .moon { display: none; }
.theme .sun { display: block; }
:root[data-theme="light"] .theme .sun { display: none; }
:root[data-theme="light"] .theme .moon { display: block; }

/* ---------- Main column ---------- */
main {
  margin-left: var(--side);
  max-width: calc(var(--side) + var(--col) + 72px);
  padding: 44px 24px 90px 48px;
}
h1 {
  margin: 0 0 30px;
  font-family: var(--display); font-stretch: 112%; font-weight: 800;
  font-size: 40px; line-height: 1.1; letter-spacing: -.01em;
}
h1::after { content: ""; display: block; width: 30px; height: 3px; margin-top: 16px; background: var(--fg); }
h2 {
  font: 500 12px/1.4 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  margin: 34px 0 12px;
}
.intro p { margin-bottom: 12px; }
/* Brand call-outs under the intro: a mono label, then the names as quiet tags */
.brands { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--line); }
.brands .k { font: 500 10px/18px var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); margin-right: 6px; }
.brands .tag { color: var(--fg); }

/* ---------- Hero: the rosekuan.com layout ----------
   Two lines at 56px, medium, tracking -.06em: name in the muted tone, role in
   the bone with a prismatic split (red left, blue right) like the GIF's
   edges. Then a pause (plain margin; the band of turning squares that filled
   it was removed 2026-09-30 at Josie's request), then three rows of mono small
   caps, label left and value right, split by hairlines that a prismatic
   glint runs along now and then. */
.hero { margin: 0 0 44px; }
.hero h1 {
  margin: 0 0 112px; padding-top: 108px;
  font-family: var(--sans); font-stretch: normal; font-weight: 500;
  font-size: 56px; line-height: 1; letter-spacing: -.06em;
  display: flex; flex-direction: column;
}
.hero h1::after { content: none; }
.hero .name { color: var(--muted); }
.hero .role { color: var(--fg); text-shadow: -1.2px 0 rgba(255, 59, 48, .55), 1.2px 0 rgba(47, 107, 255, .55); }
.hero .band { display: none; }
.hero .row {
  position: relative; container-type: inline-size;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  min-height: 44px; padding: 12px 0;
  font: 500 13px/20px var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted);
}
.hero .row + .row { border-top: 1px solid var(--line); }
.hero .row + .row::before {
  content: ""; position: absolute; top: -1px; left: 0; width: 72px; height: 1px; pointer-events: none; opacity: 0;
  background: linear-gradient(90deg, transparent, var(--prism-r), var(--prism-y), var(--prism-c), var(--prism-b), transparent);
  animation: glint 12s linear infinite;
}
.hero .row:nth-child(3)::before { animation-delay: 6s; }
@keyframes glint {
  0%   { transform: translateX(-72px); opacity: 0; }
  2%   { opacity: 1; }
  16%  { opacity: 1; }
  18%  { transform: translateX(100cqw); opacity: 0; }
  100% { transform: translateX(100cqw); opacity: 0; }
}
.hero .k { flex: 0 1 auto; white-space: pre-wrap; }
.hero .v { flex: 0 1 auto; display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 4px 16px; text-align: right; }
.hero .v a { color: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; transition: color .15s; }
.hero .v a:hover { color: var(--fg); }
.hero .arr { width: 8px; height: 8px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.hero .clock { font-variant-numeric: tabular-nums; }
/* Light theme (Josie, 2026-09-30: "the rainbows on the white are too
   distracting"): the red/blue split and the hairline glint at a third of
   their strength on the bone page. */
:root[data-theme="light"] .hero .role { text-shadow: -1px 0 rgba(255, 59, 48, .22), 1px 0 rgba(47, 107, 255, .22); }
:root[data-theme="light"] .hero .row + .row::before { background: linear-gradient(90deg, transparent, rgba(255, 59, 48, .35), rgba(255, 214, 10, .35), rgba(52, 226, 255, .35), rgba(47, 107, 255, .35), transparent); }

/* Tags: quiet mono labels (the brands row, blog tags). */
.tag {
  display: inline-block; vertical-align: middle;
  font: 500 11px/18px var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); text-decoration: none; white-space: nowrap;
}

/* Filter chips and the tag on each log card: small solid pills with a
   four-point sparkle, like a name chip (Josie, 2026-09-30: "i want these to
   look like tags on the filter and the content card", then "make them small
   and black with white type on light mode and have the same glitchy
   background without turning the shape like these squares"). Filled with the
   page ink (black + white type on the white page, bone + black on the dark
   one) and edged with the lattice squares' prismatic split: red one way, blue
   the other, a little yellow above. The split stays thin and faint, then
   flares for a moment a couple of times a cycle, like a square's does while it
   turns; the pill itself never moves. */
:root {
  --fr-idle: -1.2px 0 0 color-mix(in srgb, var(--prism-r) 60%, transparent), 1.2px 0 0 color-mix(in srgb, var(--prism-b) 60%, transparent), 0 -.8px 0 color-mix(in srgb, var(--prism-y) 35%, transparent);
  --fr-hot: -3px .4px 0 var(--prism-r), 3px -.4px 0 var(--prism-b), 0 -1.8px 0 color-mix(in srgb, var(--prism-y) 70%, transparent);
}
.filter { margin: 30px 0 8px; display: flex; flex-wrap: wrap; gap: 8px; }
.filter .tag, .entry .head .tag {
  display: inline-flex; align-items: center; gap: 5px;
  font: 500 11px/1 var(--sans); letter-spacing: 0; text-transform: capitalize;
  color: var(--bg); background: var(--fg); border: 0; border-radius: 999px;
  padding: 5px 10px 5px 8px;
  box-shadow: var(--fr-idle);
  animation: tag-glitch 7s ease-in-out infinite;
  transition: color .15s, background-color .15s;
}
.filter .tag { cursor: pointer; }
.filter .tag::before, .entry .head .tag::before {
  content: ""; flex: none; width: 8px; height: 8px; opacity: .8; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C12 7 17 12 24 12 17 12 12 17 12 24 12 17 7 12 0 12 7 12 12 7 12 0Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C12 7 17 12 24 12 17 12 12 17 12 24 12 17 7 12 0 12 7 12 12 7 12 0Z'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* the flare: wider and full-strength for a beat, with a one-frame jitter, then back to the faint split */
@keyframes tag-glitch {
  0%, 44%, 50%, 78%, 83%, 100% { box-shadow: var(--fr-idle); }
  46%  { box-shadow: var(--fr-hot); }
  47%  { box-shadow: -2px -.6px 0 var(--prism-r), 3.4px .6px 0 var(--prism-b), .6px -1.4px 0 var(--prism-y); }
  48%  { box-shadow: var(--fr-hot); }
  80%  { box-shadow: -2.4px 0 0 var(--prism-r), 2.4px 0 0 var(--prism-b), 0 -1.4px 0 var(--prism-y); }
}
/* each pill flares on its own clock */
.filter .tag:nth-child(3n+2), .entry:nth-child(3n+2) .head .tag { animation-delay: -2.3s; }
.filter .tag:nth-child(3n),   .entry:nth-child(3n) .head .tag   { animation-delay: -4.9s; }
.filter .tag:nth-child(4n+1), .entry:nth-child(4n+1) .head .tag { animation-duration: 8.6s; }
@media (prefers-reduced-motion: reduce) { .filter .tag, .entry .head .tag { animation: none; } }
/* hover: a thin blue ring outside the split; selected: the pill turns blue */
.filter .tag:hover { outline: 1.5px solid var(--blue); outline-offset: 3px; }
.filter .tag.on { background: var(--blue); color: #fff; }

/* Cards: a cell of the lattice, with a dot at each corner like the crossings */
.entry, .cv section {
  position: relative;
  background: var(--card); border: 1px solid var(--line); border-radius: 4px;
}
.entry::before, .cv section::before {
  content: ""; position: absolute; inset: -3px; pointer-events: none; opacity: .75;
  background:
    radial-gradient(circle, var(--node) 1.5px, transparent 2px) 0 0 / 6px 6px no-repeat,
    radial-gradient(circle, var(--node) 1.5px, transparent 2px) 100% 0 / 6px 6px no-repeat,
    radial-gradient(circle, var(--node) 1.5px, transparent 2px) 0 100% / 6px 6px no-repeat,
    radial-gradient(circle, var(--node) 1.5px, transparent 2px) 100% 100% / 6px 6px no-repeat;
}
.entry {
  margin-top: 24px; padding: 22px 24px 24px;
  scroll-margin-top: 16px;
  transition: border-color .2s, background-color .2s, box-shadow .2s;
}
.entry[hidden] { display: none; }
/* selected entry: no dark outline; the same soft raised look as the tree's selected row, keeping the veil's rounded spread (Josie, 2026-09-30) */
.entry.sel { border-color: transparent; }
.entry .date { font: 500 12px/1.4 var(--mono); letter-spacing: .06em; color: var(--muted); margin: 0 0 10px; }
.entry .head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 8px; }
.entry .head .title { font-weight: 600; font-size: 17px; letter-spacing: -.01em; }
.entry .head span.title { color: var(--fg); }
.entry .head a.title { text-decoration: none; }
.entry .head a.title:hover { text-decoration: underline; }
.entry .text { margin: 0; }
.shot { margin: 16px 0 0; padding: 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); }
.shot img { width: 100%; max-height: 380px; object-fit: cover; object-position: top; border-radius: 3px; }
.shot.small { display: inline-block; padding: 12px; }
.shot.small img { width: 120px; height: 120px; border-radius: 26px; }
.shot.row { display: flex; gap: 10px; padding: 12px; justify-content: center; }
.shot.row img { width: auto; height: 300px; max-height: none; border-radius: 6px; }
.caption { font: 12px/1.5 var(--mono); color: var(--muted); margin: 10px 0 0; }
.empty { color: var(--muted); padding-top: 36px; }

/* ---------- CV page ---------- */
.cv section { margin-top: 24px; padding: 22px 24px; }
.cv section:first-child { margin-top: 0; }
.cv h2 { margin-top: 0; }
.emp { display: grid; grid-template-columns: 150px 1fr; gap: 8px 20px; }
.emp .org { color: var(--muted); }
.emp .role b { font-weight: 600; }
.emp .role .dates { color: var(--muted); font: 13px/1.5 var(--mono); }
.emp .role .dates::before { content: " • "; }
.cv ul { padding-left: 20px; margin: 0; }
.cv li { margin: 0 0 6px; }
.cv ul.plain { list-style: none; padding: 0; }

/* ---------- Blog page ----------
   The list reuses the log's .entry cards. A single post is one raised card of
   prose; code sits in a pressed well like the screenshots do. */
.blog .lede { color: var(--muted); margin: 0; }
.blog .entry .tags { margin: 10px 0 0; display: flex; gap: 12px; flex-wrap: wrap; }
.blog .back { font-size: 13px; margin: 0 0 14px; }
.blog .back a { color: var(--muted); text-decoration: none; }
.blog .back a:hover { color: var(--link); }
.post {
  padding: 26px 28px 30px;
  border-radius: 20px; box-shadow: var(--raised), inset 0 1px 0 var(--glass-hi);
}
.post .date { font-size: 13px; color: var(--muted); margin: 0 0 18px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.post h2 { font-size: 20px; font-weight: 600; margin: 30px 0 10px; }
.post h3 { font-size: 16px; font-weight: 600; margin: 24px 0 8px; }
.post h4 { font-size: 15px; font-weight: 600; margin: 20px 0 6px; }
.post > :first-child + h2, .post > :first-child + h3 { margin-top: 0; }
.post p, .post ul, .post ol { margin: 0 0 14px; }
.post ul, .post ol { padding-left: 22px; }
.post li { margin-bottom: 4px; }
.post blockquote { margin: 0 0 14px; padding: 2px 0 2px 16px; border-left: 3px solid var(--line); color: var(--muted); }
.post blockquote p { margin: 0; }
.post hr { border: 0; height: 1px; margin: 24px 0; background: var(--sh-dark); box-shadow: 0 1px 0 var(--sh-light); }
.post code { font: 13px/1.5 var(--mono); padding: 1px 6px; border-radius: 6px; background: var(--box); }
.post pre.code {
  position: relative; margin: 0 0 16px; padding: 14px 16px;
  border-radius: 14px; box-shadow: var(--pressed); background: var(--bg);
  overflow-x: auto;
}
.post pre.code code { display: block; padding: 0; background: none; font-size: 13px; line-height: 1.55; white-space: pre; }
.post pre.code[data-lang]::before {
  content: attr(data-lang); position: absolute; right: 12px; top: 8px;
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.post .shot { margin: 4px 0 16px; }

/* ---------- Small screens ---------- */
@media (max-width: 720px) {
  :root { --cell: 56; }
  .side {
    position: static; width: auto; overflow: visible;
    flex-direction: row; flex-wrap: wrap; align-items: center;
    padding: 14px 16px; gap: 12px;
  }
  .who { flex: 1; }
  .who b { flex: 1; }
  .tree-toggle {
    display: inline-flex; align-items: center; gap: 6px;
    font: 500 12px/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
    padding: 9px 12px; border: 1px solid var(--line); border-radius: 6px; background: transparent; cursor: pointer;
  }
  .tree-toggle[aria-expanded="true"] { color: var(--bg); background: var(--fg); border-color: var(--fg); }
  .tree-head, .tree { flex-basis: 100%; }
  .tree-head, .tree { display: none; }
  .side.open .tree-head, .side.open .tree { display: block; }
  .theme { margin: 0; }
  main { margin-left: 0; padding: 20px 16px 60px; max-width: none; }
  h1 { font-size: 32px; margin-bottom: 22px; }
  .hero h1 { font-size: 48px; padding-top: 56px; margin-bottom: 0; }
  .hero .band { height: 112px; margin: 32px 0 24px; }
  .hero .row { gap: 16px; }
  .entry { padding: 18px 18px 20px; }
  .post { padding: 18px 18px 20px; }
  .emp { grid-template-columns: 1fr; gap: 2px; }
  .emp .org { margin-top: 10px; }
  .shot.row img { height: 220px; }
}

@media (prefers-reduced-motion: reduce) {
  .hero .row + .row::before { animation: none; }
  .tree .sq, .tree .tw .ic { transition: none; }
}
/* ---- readability + colour pass (Josie, 2026-09-30: "this is hard to read
   and can we add pops of brand color in with the type") ---- */
:root { --veil: rgba(5, 5, 5, .72); }
:root[data-theme="light"] { --veil: rgba(255, 255, 255, .9); --node-alpha: .18; --grid: #ECECEC; }
/* a veil behind the reading column so the lattice sits in the margins and only faintly under the type */
/* the veil hugs each text block (background + spread shadow), so the band of
   turning squares and the margins keep the full lattice */
.hero h1, .hero .meta, .intro, .brands, .filter, .entry, .cv > *, .post, .posts, .blog-head { position: relative; background: var(--veil); box-shadow: 0 0 0 14px var(--veil); border-radius: 3px; }
/* small mono labels: heavier */
.hero .row, .brands .tag, .entry .date, .brands .k, .caption { font-weight: 600; }
/* pops of the palette in the type: blue name and links, vermilion labels and dates, magenta brands key */
.hero .name { color: var(--blue); }
.hero .k { color: var(--verm); }
.hero .v a { color: var(--blue); }
.hero .v a:hover { color: var(--fg); }
.intro a { text-decoration-color: var(--blue); }
.brands .k { color: var(--mag); }
.entry .date { color: var(--verm); }
.tree .folder > .row .lbl { color: var(--fg); }
@media (max-width: 720px) { .hero h1, .hero .meta, .intro, .brands, .filter, .entry, .cv > *, .post, .posts, .blog-head { box-shadow: 0 0 0 10px var(--veil); } }

/* ---- selected page in the tree (Josie, 2026-09-30): a soft raised row instead
   of the browser's blue focus ring, and its square turns like the band ---- */
/* --raise is the rim from the home page (Josie, 2026-09-30: "use this treatment on everything", square corners): raised outer edge, pressed inner edge, no fill */
:root { --raise-bg: #121212; --raise: -3px -3px 8px rgba(255, 255, 255, .05), 4px 4px 10px rgba(0, 0, 0, .75), inset 3px 3px 8px rgba(0, 0, 0, .75), inset -3px -3px 8px rgba(255, 255, 255, .05); }
:root[data-theme="light"] { --raise-bg: #F4F4F6; --raise: -3px -3px 8px #FFFFFF, 4px 4px 9px rgba(0, 0, 0, .10), inset 3px 3px 8px rgba(0, 0, 0, .10), inset -3px -3px 8px #FFFFFF; }
.tree .row:focus { outline: none; }
.tree .row.sel, .tree .row:focus-visible { background: transparent; box-shadow: var(--raise); border-radius: 0; }
.tree .row.sel .lbl { font-weight: 600; }
/* the selected log entry, raised the same way; the shadows carry the veil's spread so they show outside it */
:root { --veil-sp: 14px; --raise-dk: rgba(0, 0, 0, .7); --raise-lt: rgba(255, 255, 255, .05); }
:root[data-theme="light"] { --raise-dk: rgba(0, 0, 0, .09); --raise-lt: #FFFFFF; }
@media (max-width: 720px) { :root { --veil-sp: 10px; } }
.entry.sel { background: var(--raise-bg); box-shadow: 0 0 0 var(--veil-sp) var(--raise-bg), 6px 6px 14px var(--veil-sp) var(--raise-dk), -4px -4px 12px var(--veil-sp) var(--raise-lt); }
@keyframes sq-turn {
  0%, 40%   { transform: rotate(0deg);  filter: drop-shadow(0 0 0 transparent) drop-shadow(0 0 0 transparent); }
  44%       { filter: drop-shadow(-1.2px 0 0 var(--prism-r)) drop-shadow(1.2px 0 0 var(--prism-b)); }
  48%, 88%  { transform: rotate(45deg); filter: drop-shadow(0 0 0 transparent) drop-shadow(0 0 0 transparent); }
  92%       { filter: drop-shadow(-1.2px 0 0 var(--prism-r)) drop-shadow(1.2px 0 0 var(--prism-b)); }
  96%, 100% { transform: rotate(90deg); filter: drop-shadow(0 0 0 transparent) drop-shadow(0 0 0 transparent); }
}
.tree a.row.sel .sq { animation: sq-turn 5.4s cubic-bezier(.65, 0, .2, 1) infinite; }
@media (prefers-reduced-motion: reduce) { .tree a.row.sel .sq { animation: none; } }

/* ---- home page treatment (Josie, 2026-09-30, from a crop of the Quote On card's
   rounded corner beside a grid line: "this page's treatment needs to match the
   hp treatments"). What the home page settled that night comes across:
   square corners on every container, the column a whole number of 72px cells
   with each card one pixel wider so its left and right hairlines sit on two
   grid lines, and hover / selected as soft blocks cut from the surface colour
   (--neu, the home page's tokens): raised on hover, pressed in when selected.
   The veil no longer spreads past a block (that spread was the rounded halo in
   the crop); the text blocks carry a card's 24px inset instead, so their edges
   sit on the grid as well. The column is 12 cells (864px; main's max-width is
   border-box, so --col is what is left after the sidebar and the paddings;
   it was 840 before). The image well is a pressed trough like the home page's
   progress bar. The tree's selected row is pressed, hover raised. ---- */
:root { --neu: #151515; --neu-lt: rgba(255, 255, 255, .07); --neu-dk: rgba(0, 0, 0, .85);
        --raise-sm: -2px -2px 5px var(--neu-lt), 3px 3px 6px var(--neu-dk);
        --raise-lg: -5px -5px 12px var(--neu-lt), 7px 7px 16px var(--neu-dk);
        --press-sm: inset 2px 2px 4px var(--neu-dk), inset -2px -2px 4px var(--neu-lt);
        --press-lg: inset 5px 5px 12px var(--neu-dk), inset -5px -5px 12px var(--neu-lt);
        --col: 864px; --hx: 24px; }
:root[data-theme="light"] { --neu: #F3F4F6; --neu-lt: #FFFFFF; --neu-dk: rgba(10, 10, 10, .14); }
/* on the grid: the column is whole cells at every width above the phone break (main's left edge is already 4 cells in) */
@media (min-width: 721px) { main > * { max-width: round(down, 100%, 72px); } }
/* square, no spread: the veil is the block itself */
.hero h1, .hero .meta, .intro, .brands, .filter, .entry, .cv > *, .post { border-radius: 0; box-shadow: none; }
.hero h1, .cv > h1 { padding-left: var(--hx); padding-right: var(--hx); }
.hero .row { padding: 12px var(--hx); }
@keyframes glint {
  0%   { transform: translateX(-72px); opacity: 0; }
  2%   { opacity: 1; }
  16%  { opacity: 1; }
  18%  { transform: translateX(calc(100cqw + 2 * var(--hx))); opacity: 0; }
  100% { transform: translateX(calc(100cqw + 2 * var(--hx))); opacity: 0; }
}
.intro { padding: 14px var(--hx) 2px; }
.brands { margin-left: calc(-1 * var(--hx)); margin-right: calc(-1 * var(--hx)); padding-left: var(--hx); padding-right: var(--hx); }
.filter { padding: 12px var(--hx); }
/* cards: one pixel wider than the column so both hairlines sit on grid lines; hover raised, selected pressed */
.entry, .cv section { width: calc(100% + 1px); }
.entry { transition: border-color .2s, background-color .2s, box-shadow .25s; }
@media (hover: hover) { .entry:hover { background: var(--neu); box-shadow: var(--raise-lg); } }
.entry.sel, .entry.sel:hover { border-color: var(--line); background: var(--neu); box-shadow: var(--press-lg); }
/* the image well is a pressed trough in the surface colour, square */
.shot { border-radius: 0; background: var(--neu); box-shadow: var(--press-sm); }
.shot img, .shot.row img { border-radius: 0; }
/* tree rows: square; hover raised, selected pressed (the old square rim is history) */
.tree .row { border-radius: 0; }
.tree .row:hover { background: var(--neu); box-shadow: var(--raise-sm); }
.tree .row.sel, .tree .row.sel:hover, .tree .row:focus-visible { background: var(--neu); box-shadow: var(--press-sm); }
@media (max-width: 720px) { :root { --hx: 18px; } }
@media (prefers-reduced-motion: reduce) { .entry { transition: none; } }
