/* ==========================================================================
   rexchekal.com: the Play / Work board (2026-10-22)
   Layout mined from juanmoraromero.com (docs/mined/2026-10-22-juanmoraromero-design):
   one screen drawn by hairlines, a left column of facts, a statement, a stage
   where the work sits. Colour comes from the tokens' roles (assets/tokens.css);
   type is Geist, the house stand-in, in two sizes.
   ========================================================================== */
:root {
  --sans: "Geist", ui-sans-serif, system-ui, sans-serif;
  --ui: 14px;                                         /* every small line on the board */
  --stmt: clamp(28px, min(1.2rem + 2.4vw, 5.4svh), 60px); /* the one large size; bound by height so it fits short windows */
  --hdr: 64px;
  --left: clamp(280px, 26vw, 400px);                  /* the left column */
  --pad: 16px;
  --line: color-mix(in oklab, var(--ink) 16%, var(--ground)); /* the hairlines */
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--ground); color: var(--ink); font: 500 var(--ui)/1.3 var(--sans); }
p, h1 { margin: 0; }
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
.mut { color: var(--muted); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Links on the board change colour on hover; the active tab is ink, the rest muted */
.hdr a, .left a, .tab { transition: color .15s; }
@media (hover: hover) and (pointer: fine) {
  .hdr a:hover, .left a:hover { color: var(--ink-hover); }
  .tab[aria-selected="false"]:hover { color: var(--ink); }
}

/* ---- header ------------------------------------------------------------- */
.hdr { position: sticky; top: 0; z-index: 5; height: var(--hdr); display: grid; grid-template-columns: var(--left) 1fr auto;
  align-items: center; padding-right: var(--pad); background: var(--ground); border-bottom: 1px solid var(--line); }
.hdr-name { padding-left: var(--pad); }
/* Play / Work: the site's main switch, so it is drawn as one: a big segmented
   control, the selected half filled with the ink */
.tabs { display: flex; padding: 4px; gap: 4px; margin-left: var(--pad); justify-self: start; border-radius: 999px; background: var(--panel); }
.tab { padding: 8px 24px; border-radius: 999px; font-size: 22px; line-height: 1; letter-spacing: -0.01em; color: var(--muted); transition: color .15s, background-color .15s; }
.tab[aria-selected="true"] { background: var(--ink); color: var(--ground); }
.hdr-contact { text-decoration: underline; text-underline-offset: 3px; }

.hdr-end { display: flex; align-items: center; gap: var(--pad); }

/* ---- theme controls, moved verbatim from site.css (2026-10-23) ------------
   A dark-mode switch that inverts the page, and a shuffle for a random
   colour. The switch is drawn in the ink with the ground cut out of it, so
   it contrasts on every theme; it reads "dark" when the page really is the
   darker of the pair. Sun left, moon right, the knob covers one. */
.theme-ctl { flex: none; display: flex; align-items: center; gap: 8px; }
.mode-toggle { position: relative; display: block; flex: none; width: 48px; height: 26px; padding: 0; border: 0; border-radius: 99px;
  background: var(--ink); color: var(--ground); cursor: pointer; }
.mode-knob { position: absolute; z-index: 1; top: 4px; left: 4px; width: 18px; height: 18px; border-radius: 50%; background: var(--ground);
  transition: transform 220ms cubic-bezier(.3, .7, .2, 1); }
.mode-sun, .mode-moon { position: absolute; top: 6px; width: 14px; height: 14px; display: block; transform-origin: 50% 50%;
  transition: transform 280ms cubic-bezier(.34, 1.56, .64, 1); }
.mode-sun  { left: 6px;  transform: scale(.55); }
.mode-moon { right: 6px; transform: scale(1); }
.mode-toggle[aria-checked="true"] .mode-knob { transform: translateX(22px); }
.mode-toggle[aria-checked="true"] .mode-sun  { transform: scale(1); }
.mode-toggle[aria-checked="true"] .mode-moon { transform: scale(.55); }
.shuffle-btn { appearance: none; display: grid; place-items: center; flex: none; width: 34px; height: 34px; padding: 0; border: 0; border-radius: 99px;
  background: transparent; color: inherit; cursor: pointer; transition: background-color 150ms ease-out; }
.shuffle-btn svg { width: 20px; height: 20px; display: block; }
@media (hover: hover) and (pointer: fine) { .shuffle-btn:hover { background: var(--ghost); } }
.mode-toggle:focus-visible, .shuffle-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.mode-toggle:focus-visible { outline-color: var(--ink); }

/* ---- the board: one screen on a desktop --------------------------------- */
.board { display: grid; grid-template-columns: var(--left) 1fr; grid-template-rows: minmax(0, 46fr) minmax(0, 54fr);
  height: calc(100svh - var(--hdr)); }
/* the left column shares the board's two rows, so its divider is the board's midline */
.left { grid-row: 1 / 3; display: grid; grid-template-rows: subgrid; border-right: 1px solid var(--line); }
.left-top, .left-bot { display: flex; flex-direction: column; justify-content: space-between; gap: var(--pad); padding: var(--pad); min-height: 0; }
.left-top { border-bottom: 1px solid var(--line); }
.who { display: grid; gap: 4px; }
.links { display: flex; justify-content: space-between; gap: var(--pad); }
.facts { display: grid; gap: 12px; }
.facts-row { display: flex; justify-content: space-between; align-items: start; gap: var(--pad); }
.view { text-decoration: underline; text-underline-offset: 3px; }
.facts-line { color: var(--muted); max-width: 36ch; }
/* the mark, large in the corner: a signature, the way the source signs with its shapes */
.big-mark { flex: none; width: clamp(72px, 9vw, 128px); aspect-ratio: 1; background: var(--ink);
  -webkit-mask: url(/assets/img/mark.svg) center / contain no-repeat; mask: url(/assets/img/mark.svg) center / contain no-repeat; }

.statement { padding: calc(var(--pad) * 1.5) var(--pad) var(--pad); border-bottom: 1px solid var(--line); overflow: hidden; }
.stmt { font: 500 var(--stmt)/0.98 var(--sans); letter-spacing: -0.03em; max-width: 24ch; text-indent: 2.5em; }

/* ---- the stage: the active tab's row, scrolling sideways ------------------
   Every tile is the row's full height; the row scrolls natively (trackpad,
   swipe, wheel) and snaps each tile to the left edge. */
.stage { grid-column: 2; grid-row: 2; position: relative; min-height: 0; overflow: hidden; }
.stage[hidden] { display: none; }
.count { position: absolute; top: var(--pad); right: var(--pad); z-index: 2; }
.row { position: absolute; left: 0; right: 0; bottom: var(--pad); top: calc(var(--pad) * 3);
  display: flex; gap: var(--pad); padding: 0 var(--pad); overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scroll-padding: 0 var(--pad); scrollbar-width: none; overscroll-behavior-x: contain; }
.row::-webkit-scrollbar { display: none; }
.row::after { content: ""; flex: none; width: 1px; }   /* keeps the last tile's right padding */
.tile { flex: none; height: 100%; aspect-ratio: 1; overflow: hidden; background: var(--image); scroll-snap-align: start; }
.tile img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s cubic-bezier(.19, 1, .22, 1), opacity .15s; }
@media (hover: hover) and (pointer: fine) { .tile:hover img { transform: scale(1.04); opacity: .9; } }
.tile img[src$=".svg"] { object-fit: contain; padding: 14%; }

/* ---- below a desktop: the page scrolls, the row swipes ------------------- */
@media (max-width: 899px), (max-height: 599px) {
  /* the theme controls take the header's room on a phone, so the tabs drop to a row of their own */
  :root { --hdr: 106px; }   /* two rows: name and controls, then the Play / Work switch */
  .hdr { height: auto; grid-template-columns: 1fr auto; grid-template-areas: "name end" "tabs tabs"; }
  .hdr-name { grid-area: name; height: 48px; display: flex; align-items: center; }
  .hdr-end { grid-area: end; }
  .tabs { grid-area: tabs; justify-self: stretch; margin: 0 0 12px var(--pad); }
  .tab { flex: 1; text-align: center; font-size: 18px; }
  .board { display: flex; flex-direction: column; height: auto; }
  .statement { order: 1; } .stage { order: 2; } .facts { order: 3; } .big-mark { order: 4; }
  .left, .left-top, .left-bot { display: contents; }
  .who, .links { display: none; }
  .statement { padding: 32px var(--pad); }
  .stmt { text-indent: 0; }
  .stage { padding: 0; }
  .count { position: static; padding: var(--pad); }
  .row { position: static; height: 72vw; max-height: 420px;
    scrollbar-width: none; padding: 0 var(--pad); scroll-padding: 0 var(--pad); }
  .row::-webkit-scrollbar { display: none; }
  .tile { scroll-snap-align: start; height: 100%; }
  .facts { margin: 0; border-top: 1px solid var(--line); padding: var(--pad); }
  .big-mark { display: block; margin: 48px var(--pad) var(--pad); }
}

/* ==== the project page: glass cards that scroll sideways ===================
   Rex, 2026-10-23: "could it open big horizontally scrolling glass cards? with
   the case study broken out and images?" Behind the cards, the project's own
   cover, blurred and washed in the page colour, so the glass has something to
   frost. Cards are the page colour at 85% with a backdrop blur; all text sits
   on glass, never on the raw image: at these values ink and muted text clear
   AA in every theme even over a pure black or white pixel (worst 4.79:1,
   measured 2026-10-23). The page arrives with a cross-fade. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

.is-project { overflow: hidden; }
.glass-bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; background: var(--ground); }
.glass-bg img { width: 100%; height: 100%; object-fit: cover; filter: blur(48px) saturate(1.3); transform: scale(1.2); opacity: .6; }
.glass-bg::after { content: ""; position: absolute; inset: 0; background: color-mix(in oklab, var(--ground) 50%, transparent); }

.proj { height: calc(100svh - var(--hdr)); display: grid; grid-template-rows: auto 1fr; }
/* the bar's text needs glass under it too */
.proj-bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--pad); margin: var(--pad); padding: 12px var(--pad); border-radius: 999px;
  background: color-mix(in oklab, var(--ground) 85%, transparent); -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
  border: 1px solid color-mix(in oklab, var(--ink) 12%, transparent); }
.proj-count { font-variant-numeric: tabular-nums; }
.proj-end { display: flex; justify-content: end; gap: 24px; }
.proj-prev, .proj-next { color: var(--muted); }
.proj-close, .u { text-decoration: underline; text-underline-offset: 3px; }
.proj a { transition: color .15s; }
@media (hover: hover) and (pointer: fine) { .proj-prev:hover, .proj-next:hover { color: var(--ink); } .proj-close:hover, .glass a:hover { color: var(--ink-hover); } }

.glass-row { list-style: none; margin: 0; padding: 0 var(--pad) calc(var(--pad) * 2); display: flex; gap: var(--pad); align-items: stretch;
  overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scroll-padding: 0 var(--pad); scrollbar-width: none; overscroll-behavior-x: contain; }
.glass-row::-webkit-scrollbar { display: none; }
.glass-row::after { content: ""; flex: none; width: 1px; }
.glass { flex: none; scroll-snap-align: start; border-radius: 24px; overflow: hidden;
  background: color-mix(in oklab, var(--ground) 85%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(1.4); backdrop-filter: blur(24px) saturate(1.4);
  border: 1px solid color-mix(in oklab, var(--ink) 12%, transparent); }
.glass-title, .glass-text { width: min(560px, 82vw); padding: 40px; display: flex; flex-direction: column; gap: 16px; }
.glass-title { justify-content: end; }
.glass-title h1 { font: 500 var(--stmt)/0.98 var(--sans); letter-spacing: -0.03em; }
.glass-line { font-size: 20px; line-height: 1.3; }
.glass-text { justify-content: center; }
.glass-text p:last-child { font-size: clamp(20px, 1rem + 1vw, 30px); line-height: 1.25; letter-spacing: -0.01em; }
.glass-img { padding: 16px; display: grid; place-items: center; }
.glass-img img { height: 100%; width: auto; max-width: min(1100px, 86vw); object-fit: contain; border-radius: 12px; }
.glass-img.is-mark img { height: 60%; padding: 0 64px; border-radius: 0; }

@media (max-width: 899px) {
  .proj-bar { grid-template-columns: 1fr auto; }
  .proj-prev { display: none; }
  .proj-end .proj-next { display: none; }
  .glass-title, .glass-text { padding: 24px; }
  .glass-img img { max-width: 82vw; height: auto; max-height: 100%; }
}

/* ==== About: a glass card in a dialog ======================================
   Rex, 2026-10-23: "there should be an about link that opens up a modal about me." */
.hdr-about { appearance: none; border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer; transition: color .15s; }
@media (hover: hover) and (pointer: fine) { .hdr-about:hover { color: var(--ink-hover); } }
.about { width: min(640px, calc(100vw - 32px)); max-height: calc(100svh - 32px); margin: auto; padding: 40px; color: var(--ink);
  display: none; flex-direction: column; gap: 16px; }
.about[open] { display: flex; overflow-y: auto; }   /* .glass clips; About scrolls when the screen is short */
.about h2 { font: 500 var(--stmt)/0.98 var(--sans); letter-spacing: -0.03em; margin: 0 0 8px; }
.about p { margin: 0; font-size: 18px; line-height: 1.45; }
.about .mut { font-size: inherit; }
.about-links { display: flex; gap: 24px; flex-wrap: wrap; }
.about form { margin: 8px 0 0; }
.about-close { appearance: none; border: 0; background: none; padding: 0; font: inherit; color: inherit; cursor: pointer; }
.about::backdrop { background: color-mix(in oklab, var(--ground) 40%, transparent); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); }
@media (prefers-reduced-motion: no-preference) {
  .about[open] { animation: about-in .35s cubic-bezier(.19, 1, .22, 1); }
  @keyframes about-in { from { opacity: 0; transform: translateY(16px) scale(.98); } }
}
@media (max-width: 899px) { .about { padding: 24px; } .about p { font-size: 16px; } }
