/* ==========================================================================
   Index Express — site stylesheet
   Hand-written. No build step, no framework, no CDN, no external font.

   PALETTE: the studio's own editor theme (slate + teal + orange), which has
   measured contrast ratios. The logo's navy/violet/gold is NOT used as site
   chrome — it gets its own dark navy panel so the two never fight.

   ACCESSIBILITY NOTE: the source palette's secondary text (#6B7683) measures
   4.09:1 on the page ground, which FAILS WCAG AA for body text. This sheet
   uses #8592A2 instead (5.97:1 on --bg0, 4.51:1 on --bg3).
   ========================================================================== */

/* --------------------------------------------------------------- tokens */
:root {
  /* ground, darkest first */
  --bg0:        #0E1116;   /* page */
  --bg1:        #151A21;   /* header, footer, panel */
  --bg2:        #1C232D;   /* raised surface, card */
  --bg3:        #222B37;   /* resting interactive chrome */
  --bg-hover:   #2C3847;   /* neutral hover — hover is never the accent */
  --navy:       #090F22;   /* the logo's own ground, used ONLY behind the logo */

  /* ink */
  --text:       #C7D0D9;   /* 12.1:1 on --bg0 (AAA) */
  --text-dim:   #8592A2;   /* 5.97:1 on --bg0 (AA) */
  --text-loud:  #EEF3F7;

  /* accents — teal is STATE (focus, current, selection); orange is ACTION */
  --teal:       #35E0D0;   /* 11.5:1 on --bg0 */
  --teal-dim:   #23B7AA;
  --cyan:       #47C7E8;
  --orange:     #FF8A3D;   /* 8.1:1 on --bg0 */
  --on-accent:  #0D0F14;   /* near-black for text ON a solid accent fill */

  --border:     #2A3542;
  --border-lit: #4D6279;   /* 3.01:1 on --bg0 — meets the non-text minimum */

  /* type scale */
  --f-xs:   0.78rem;
  --f-sm:   0.875rem;
  --f-base: 1rem;
  --f-lg:   1.125rem;
  --f-xl:   clamp(1.35rem, 1.1rem + 1.1vw, 1.75rem);
  --f-2xl:  clamp(1.75rem, 1.3rem + 2.1vw, 2.5rem);
  --f-3xl:  clamp(2.25rem, 1.5rem + 3.4vw, 3.75rem);

  /* spacing */
  --s1: 0.25rem; --s2: 0.5rem;  --s3: 0.75rem; --s4: 1rem;
  --s5: 1.5rem;  --s6: 2rem;    --s7: 3rem;    --s8: 4rem;  --s9: 6rem;

  --measure: 68ch;
  --wrap:    1180px;
  --radius:  10px;

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, "Liberation Mono", monospace;

  color-scheme: dark;
}

/* --------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg0);
  color: var(--text);
  font: var(--f-base)/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, picture, video { max-width: 100%; display: block; }

h1, h2, h3, h4 {
  color: var(--text-loud);
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0 0 var(--s4);
  font-weight: 600;
  text-wrap: balance;
}
h1 { font-size: var(--f-3xl); }
h2 { font-size: var(--f-2xl); }
h3 { font-size: var(--f-xl); }

p { margin: 0 0 var(--s4); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: var(--teal); text-decoration-color: color-mix(in srgb, var(--teal) 40%, transparent); text-underline-offset: 3px; }
a:hover { color: var(--teal); text-decoration-color: var(--teal); }

ul { padding-left: 1.15em; }
li { margin-bottom: var(--s2); max-width: var(--measure); }

hr { border: 0; border-top: 1px solid var(--border); margin: var(--s7) 0; }

/* Focus: a visible ring that never relies on the hairline border alone. */
:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
  border-radius: 3px;
}

.skip-link {
  position: absolute; left: var(--s4); top: -4rem; z-index: 100;
  background: var(--teal); color: var(--on-accent);
  padding: var(--s3) var(--s4); border-radius: var(--radius); font-weight: 600;
  transition: top .15s ease;
}
.skip-link:focus { top: var(--s4); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* --------------------------------------------------------------- layout */
.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }
.wrap-narrow { width: min(100% - 2.5rem, 780px); margin-inline: auto; }

section { padding-block: var(--s8); }
section.tight { padding-block: var(--s7); }

.lede { font-size: var(--f-lg); color: var(--text); }

.eyebrow {
  font: 600 var(--f-xs)/1 var(--mono);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--cyan); margin-bottom: var(--s3);
}

/* --------------------------------------------------------------- header */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg1) 92%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.site-header > .wrap {
  display: flex; align-items: center; gap: var(--s5);
  min-height: 64px; flex-wrap: wrap;
}

/* The logo keeps its own navy ground so the badge never sits on slate. */
.brand { display: flex; align-items: center; gap: var(--s3); text-decoration: none; color: inherit; }
.brand:hover { color: inherit; }
.brand-badge {
  width: 34px; height: 34px; border-radius: 8px;
  background: var(--navy); padding: 2px; flex: none;
}
.brand-name {
  font: 600 1.0625rem/1 var(--sans);
  letter-spacing: .11em; text-transform: uppercase; color: var(--text-loud);
}
.brand-name .x { color: var(--orange); }

.site-nav { margin-left: auto; }
.site-nav ul { display: flex; gap: var(--s5); list-style: none; margin: 0; padding: 0; flex-wrap: wrap; }
.site-nav li { margin: 0; }
.site-nav a {
  color: var(--text-dim); text-decoration: none;
  font-size: var(--f-sm); font-weight: 500;
  padding-block: var(--s2); display: inline-block;
  border-bottom: 2px solid transparent;
}
.site-nav a:hover { color: var(--text-loud); }
.site-nav a[aria-current="page"] { color: var(--text-loud); border-bottom-color: var(--teal); }

/* --------------------------------------------------------------- hero */
/* Layering here is deliberately all POSITIVE. An earlier version put the image at
   z-index:-2 and the scrim at -1 inside an `isolation:isolate` context, and the
   image did not paint at all - negative z-index inside a stacking context is
   exactly the sort of thing that behaves differently than you expect. Three
   explicit layers, bottom to top: image, scrim, content. */
.hero { position: relative; border-bottom: 1px solid var(--border); background: var(--bg0); }
.hero-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; }
/* The scrim exists ONLY to keep the headline legible, so it darkens the left third
   and then gets out of the way. An earlier version stacked two heavy gradients
   across the whole box and smothered the picture entirely - the hero read as a flat
   dark panel. Both gradients now reach full transparency before the right edge. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(14,17,22,.92) 0%, rgba(14,17,22,.62) 38%, rgba(14,17,22,0) 70%),
    linear-gradient(180deg, rgba(14,17,22,0) 45%, var(--bg0) 100%);
}
.hero-inner { position: relative; z-index: 2; padding-block: clamp(var(--s8), 14vh, 9rem); }
.hero h1 { max-width: 16ch; margin-bottom: var(--s5); }
.hero p { font-size: var(--f-lg); max-width: 56ch; color: var(--text); }

.cta-row { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }

.btn {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: var(--s3) var(--s5); border-radius: var(--radius);
  font-weight: 600; font-size: var(--f-sm); text-decoration: none;
  border: 1px solid var(--border-lit); color: var(--text-loud);
  background: var(--bg3);
  transition: background .15s ease, border-color .15s ease;
}
.btn:hover { background: var(--bg-hover); color: var(--text-loud); border-color: var(--border-lit); }
.btn-primary {
  background: var(--orange); border-color: var(--orange);
  color: var(--on-accent);            /* never white on orange */
}
.btn-primary:hover { background: #FFA163; border-color: #FFA163; color: var(--on-accent); }

/* --------------------------------------------------------------- cards */
.grid { display: grid; gap: var(--s5); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
/* Four products need a 4-up that actually fits the 1180px wrap, or auto-fit lands
   on three columns and leaves a lone orphan card on the second row. */
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }

.card {
  background: var(--bg1); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  transition: border-color .15s ease, transform .15s ease;
}
.card:hover { border-color: var(--border-lit); }
.card-media { position: relative; background: var(--bg2); aspect-ratio: 16 / 9; }
.card-media img { width: 100%; height: 100%; object-fit: cover; }
.card-body { padding: var(--s5); display: flex; flex-direction: column; flex: 1; }
.card-body h3 { margin-bottom: var(--s2); }
.card-body p { font-size: var(--f-sm); color: var(--text-dim); }
.card-body .card-foot { margin-top: auto; padding-top: var(--s4); }

/* A card for a product with no publishable screenshot yet. It holds the grid's
   rhythm without borrowing an image that would misrepresent the thing. Saying so
   in the plate is the honest option and costs nothing. */
.card-plate {
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, var(--navy) 0%, var(--bg2) 100%);
  border-bottom: 1px solid var(--border);
  color: var(--text-dim);
  font: 600 var(--f-xs)/1.4 var(--mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: center;
  padding: var(--s4);
}

.card-link { text-decoration: none; color: inherit; display: block; }
.card-link:hover { color: inherit; }
.card-link:hover h3 { color: var(--teal); }

/* ------------------------------------------------------- status pills */
.pill {
  display: inline-block; font: 600 var(--f-xs)/1 var(--mono);
  letter-spacing: .06em; text-transform: uppercase;
  padding: .34em .7em; border-radius: 999px;
  border: 1px solid var(--border-lit); color: var(--text-dim);
  background: var(--bg2); white-space: nowrap;
}
.pill-live    { color: var(--teal);   border-color: color-mix(in srgb, var(--teal) 45%, transparent); }
.pill-dev     { color: var(--orange); border-color: color-mix(in srgb, var(--orange) 45%, transparent); }
.pill-hold    { color: var(--text-dim); }

/* --------------------------------------------- honesty labels on images
   A CLOSED vocabulary. Every image on this site carries one. The label is
   real text, never an image, so it survives being screenshotted, hotlinked
   or read aloud. */
figure { margin: 0; }
figure img { border-radius: var(--radius); border: 1px solid var(--border); }

/* The contact sheets are PORTRAIT and sit in a grid beside 16:9 screenshots. Left
   alone they tower over their neighbours and the row reads as broken layout. Cap
   the height and CONTAIN rather than cover - cropping a contact sheet would cut
   off the very thing it is documenting. */
.shot-tall img {
  max-height: 560px;
  width: auto;
  margin-inline: auto;
  object-fit: contain;
}

.shot { position: relative; }
.shot-label {
  position: absolute; left: var(--s3); bottom: var(--s3);
  font: 600 var(--f-xs)/1 var(--mono);
  letter-spacing: .07em; text-transform: uppercase;
  background: rgba(9,15,34,.88); color: var(--text);
  border: 1px solid var(--border-lit);
  padding: .38em .65em; border-radius: 6px;
  backdrop-filter: blur(3px);
}
figcaption {
  font-size: var(--f-sm); color: var(--text-dim);
  margin-top: var(--s3); max-width: var(--measure);
}

/* --------------------------------------------------------------- prose */
.prose h2 { margin-top: var(--s7); }
.prose h3 { margin-top: var(--s6); }
.prose > :first-child { margin-top: 0; }

.feature-list { list-style: none; padding: 0; }
.feature-list li {
  padding-left: 1.6em; position: relative; margin-bottom: var(--s3);
}
.feature-list li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 7px; height: 7px; border-radius: 2px;
  background: var(--teal); transform: rotate(45deg);
}

/* ------------------------------------------------------------- devlog */
.post-list { list-style: none; padding: 0; margin: 0; }
.post-list li { margin-bottom: 0; border-bottom: 1px solid var(--border); }
.post-list li:first-child { border-top: 1px solid var(--border); }
.post-list a {
  display: grid; grid-template-columns: 1fr auto; gap: var(--s3) var(--s5);
  align-items: baseline; padding: var(--s5) 0; text-decoration: none; color: inherit;
}
.post-list a:hover { color: inherit; }
.post-list a:hover .post-title { color: var(--teal); }
.post-title { font-size: var(--f-lg); font-weight: 600; color: var(--text-loud); }
.post-meta { font: var(--f-xs)/1.4 var(--mono); color: var(--text-dim); letter-spacing: .05em; white-space: nowrap; }
.post-excerpt { grid-column: 1 / -1; font-size: var(--f-sm); color: var(--text-dim); margin: 0; }

article.post header { margin-bottom: var(--s6); }
article.post .post-meta { margin-bottom: var(--s3); display: block; }

/* ------------------------------------------------------------- gallery */
.gallery { display: grid; gap: var(--s6); grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
.gallery figure { display: flex; flex-direction: column; }

/* ------------------------------------------------------------- footer */
.site-footer {
  background: var(--bg1); border-top: 1px solid var(--border);
  padding-block: var(--s7); margin-top: var(--s8);
  font-size: var(--f-sm);
}
.footer-grid { display: grid; gap: var(--s6); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.footer-grid h4 { font-size: var(--f-sm); color: var(--text-loud); margin-bottom: var(--s3); }
.footer-grid ul { list-style: none; padding: 0; margin: 0; }
.footer-grid li { margin-bottom: var(--s2); }
.footer-grid a { color: var(--text-dim); text-decoration: none; }
.footer-grid a:hover { color: var(--teal); }
.footer-bottom {
  margin-top: var(--s6); padding-top: var(--s5);
  border-top: 1px solid var(--border); color: var(--text-dim);
  display: flex; flex-wrap: wrap; gap: var(--s4); justify-content: space-between;
}

/* ------------------------------------------------------------- notice */
.notice {
  background: var(--bg2); border: 1px solid var(--border);
  border-left: 3px solid var(--orange);
  border-radius: var(--radius); padding: var(--s5);
  font-size: var(--f-sm); color: var(--text-dim);
}
.notice strong { color: var(--text); }

/* ------------------------------------------------------------- motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (prefers-contrast: more) {
  :root { --text-dim: #AEBAC6; --border: #4D6279; }
}

/* ------------------------------------------------------------- narrow */
@media (max-width: 640px) {
  .site-header > .wrap { min-height: 56px; padding-block: var(--s3); }
  .site-nav { margin-left: 0; width: 100%; }
  .site-nav ul { gap: var(--s4); }
  .hero-inner { padding-block: var(--s8); }
  .post-list a { grid-template-columns: 1fr; }
  .post-meta { white-space: normal; }
}
