/* =====================================================================
   tommycunningham.uk — design system
   Dark, red accent, terminal-flavoured. One file, no build step.
   ===================================================================== */

/* ---------- Fonts (self-hosted, latin subsets) ---------- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("/assets/fonts/inter-latin.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/jetbrains-mono-latin.woff2") format("woff2");
}

/* ---------- Tokens ---------- */
:root {
  --background: #09090b;
  --surface: #111114;
  --surface-2: #17171b;
  --surface-hover: #1c1c21;
  --text: #f4f4f5;
  --text-muted: #a1a1aa;
  --text-dim: #8b8b95;
  --red: #e5192b;
  --red-bright: #ff3b4a;
  --red-text: #ff3b4a;   /* red for text on dark surfaces (>= 4.5:1) */
  --red-deep: #9f0f1d;
  --red-soft: rgba(229, 25, 43, 0.14);
  --red-glow: rgba(229, 25, 43, 0.35);
  --border: #26262c;
  --border-strong: #3a3a42;
  --focus: #ff6b75;

  /* Code / terminal surfaces only: Tommy's real PhpStorm "Dreamweaver" scheme.
     Never used for general site UI. */
  --code-bg: #1F1F1F;
  --code-bg-2: #262626;
  --code-text: #D2D4D4;
  --syntax-keyword: #5494FB;
  --syntax-string: #E8B46A;
  --syntax-number: #4CAF50;
  --syntax-function: #A681D6;
  --syntax-identifier: #B79BF7;
  --syntax-constant: #C77DBB;
  --syntax-member: #56A8F5;
  --syntax-tag: #15B8CF;
  --syntax-attr: #4CAF50;
  --syntax-php-tag: #E86868;
  --syntax-comment: #7A7E85;
  --syntax-error: #F75464;

  --radius: 12px;
  --radius-sm: 8px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;

  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --container: 1200px;
  --gutter: clamp(1rem, 3vw, 2rem);
  --header-h: 72px;

  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --dur: 220ms;
  --shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset, 0 10px 30px -12px rgba(0, 0, 0, 0.7);
  --shadow-lift: 0 1px 0 rgba(255, 255, 255, 0.04) inset, 0 18px 40px -14px rgba(0, 0, 0, 0.8), 0 0 0 1px var(--border-strong);

  color-scheme: dark;
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}
body {
  margin: 0;
  background: var(--background);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
main { flex: 1 0 auto; }
main:focus { outline: none; }
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
a:hover { color: var(--text); }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
h1, h2, h3, h4 { margin: 0; line-height: 1.15; letter-spacing: -0.02em; font-weight: 700; text-wrap: balance; }
ul, ol { margin: 0; padding: 0; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
::selection { background: var(--red); color: #fff; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 4px; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 1rem; top: -100px; z-index: 100;
  background: var(--red); color: #fff; padding: 0.6rem 1rem; border-radius: var(--radius-sm);
  font-weight: 600;
}
.skip-link:focus { top: 1rem; }

/* film grain: a fixed, non-interactive texture layer */
.grain {
  position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

/* ---------- Type utilities ---------- */
.mono { font-family: var(--font-mono); }
.t-red { color: var(--red-text); }
.t-muted { color: var(--text-muted); }
.t-dim { color: var(--text-dim); }
.lead { font-size: 1.125rem; color: var(--text-muted); }
.eyebrow a { display: inline-block; padding: 0.35rem 0; margin: -0.35rem 0; }
.eyebrow {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--red-text);
  letter-spacing: 0.02em;
  margin: 0 0 var(--space-2);
}
.section-title {
  font-family: var(--font-mono);
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  font-weight: 700;
  letter-spacing: 0;
  display: flex; align-items: center; gap: 0.6rem;
}
.section-title::before { content: "//"; color: var(--red-text); font-weight: 700; }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4);
  margin-bottom: var(--space-5);
}
.more-link {
  min-height: 32px; padding: 0.25rem 0;
  font-size: 0.9rem; font-weight: 600; color: var(--red-text);
  display: inline-flex; align-items: center; gap: 0.35rem;
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px;
  transition: text-decoration-color var(--dur) var(--ease), color var(--dur) var(--ease);
  white-space: nowrap;
}
.more-link:hover, .more-link:focus-visible { color: #ff6b75; text-decoration-color: currentColor; }
.more-link .icon { width: 1rem; height: 1rem; transition: transform var(--dur) var(--ease); }
.more-link:hover .icon { transform: translateX(3px); }

/* blinking terminal cursor */
.cursor {
  display: inline-block; width: 0.5ch; height: 1em; vertical-align: -0.12em;
  background: var(--red); margin-left: 0.1ch;
  animation: blink 1.1s steps(2, start) infinite;
}
.cursor--thin { width: 3px; }
@keyframes blink { to { visibility: hidden; } }

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.section--tight { padding-block: clamp(1.5rem, 4vw, 2.5rem); }
.section + .section { padding-top: 0; }

.grid { display: grid; gap: var(--space-4); }
.grid--projects { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--auto { grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }
.grid--home {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: auto;
  gap: var(--space-4);
}
.grid--home .span-3 { grid-column: span 3; }
.grid--home .home-aside { grid-column: 4; grid-row: span 2; }

@media (max-width: 1080px) {
  .grid--projects { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--home { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--home .span-3 { grid-column: 1 / -1; }
  .grid--home .home-aside { grid-column: 1 / -1; grid-row: auto; }
}
@media (max-width: 760px) {
  .grid--home { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--home .card--compact:nth-child(3) { grid-column: 1 / -1; }
}
@media (max-width: 600px) {
  .grid--projects, .grid--home { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--background) 82%, transparent);
  backdrop-filter: blur(12px) saturate(1.2);
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.site-header.is-scrolled { border-bottom-color: var(--border); }
.site-header--home:not(.is-scrolled):not(.nav-open) { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
/* Homepage wordmark: hidden while the hero greeting is on screen, revealed once it scrolls under the header */
.brand--dynamic {
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  /* One symmetric curve and duration for both directions, so the hide is the exact reverse of the reveal.
     The element stays in the render tree (no visibility toggling, which can skip the first frame in WebKit);
     JS sets aria-hidden / tabindex while it is hidden. */
  transition: opacity 220ms cubic-bezier(0.45, 0, 0.55, 1), transform 220ms cubic-bezier(0.45, 0, 0.55, 1);
  will-change: opacity, transform;
}
.site-header.brand-visible .brand--dynamic { opacity: 1; transform: translateY(0); pointer-events: auto; }
/* Identity alias: both wordmarks share one grid cell, so the box is always as wide as the longer one and
   the nav never moves. data-identity="slypigs" on the header (set by the hero flourish) crossfades them. */
.brand__ids { display: inline-grid; justify-items: start; }
.brand__id { grid-area: 1 / 1; transition: opacity 220ms cubic-bezier(0.45, 0, 0.55, 1), transform 220ms cubic-bezier(0.45, 0, 0.55, 1); }
.brand__id--alias { opacity: 0; transform: translateY(5px); }
.site-header[data-identity="slypigs"] .brand__id--tommy { opacity: 0; transform: translateY(-5px); }
.site-header[data-identity="slypigs"] .brand__id--alias { opacity: 1; transform: translateY(0); }
.site-header__inner {
  height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-5);
}
.brand {
  font-family: var(--font-mono); font-weight: 700; font-size: 1rem; letter-spacing: 0.06em;
  white-space: nowrap; color: var(--text);
}
.brand--small { font-size: 0.85rem; }
.brand { display: inline-flex; align-items: center; min-height: 44px; }
.site-nav { display: flex; align-items: center; gap: var(--space-5); }
.site-nav__list { list-style: none; display: flex; align-items: center; gap: clamp(0.5rem, 1.6vw, 1.5rem); }
.site-nav__list a {
  display: inline-block; padding: 0.5rem 0.25rem; font-size: 0.95rem; font-weight: 500; color: var(--text-muted);
  position: relative; transition: color var(--dur) var(--ease);
}
.site-nav__list a::after {
  content: ""; position: absolute; left: 0.25rem; right: 0.25rem; bottom: 0.15rem; height: 2px;
  background: var(--red); border-radius: 2px; transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.site-nav__list a:hover, .site-nav__list a[aria-current="page"] { color: var(--text); }
.site-nav__list a[aria-current="page"]::after, .site-nav__list a:hover::after { transform: scaleX(1); }
.nav-toggle {
  display: none; width: 44px; height: 44px; border-radius: var(--radius-sm);
  align-items: center; justify-content: center; color: var(--text);
  border: 1px solid var(--border);
}
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

@media (max-width: 860px) {
  .nav-toggle { display: inline-flex; }
  .site-nav {
    position: absolute; left: 0; right: 0; top: var(--header-h);
    background: var(--surface); border-bottom: 1px solid var(--border);
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--space-3) var(--gutter) var(--space-5);
    box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.8);
    transform-origin: top; opacity: 0; transform: translateY(-6px); visibility: hidden; pointer-events: none;
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility 0s linear var(--dur);
  }
  .js .site-header.nav-open .site-nav, .no-js .site-nav { opacity: 1; transform: none; visibility: visible; pointer-events: auto; transition-delay: 0s; }
  .no-js .site-nav { position: static; box-shadow: none; }
  .no-js .nav-toggle { display: none; }
  .site-nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .site-nav__list a { display: block; padding: 0.85rem 0.25rem; font-size: 1.05rem; border-bottom: 1px solid var(--border); }
  .site-nav__list a::after { display: none; }
  .site-nav__list a[aria-current="page"] { color: var(--red-text); }
  .site-nav__cta { margin-top: var(--space-4); justify-content: center; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 48px; padding: 0.75rem 1.4rem; border-radius: var(--radius-sm);
  font-weight: 600; font-size: 0.95rem; line-height: 1; white-space: nowrap;
  border: 1px solid transparent; cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn .icon { width: 1.1rem; height: 1.1rem; }
.btn-primary { background: var(--red); color: #fff; box-shadow: 0 8px 24px -10px var(--red-glow); }
.btn-primary:hover, .btn-primary:focus-visible { background: var(--red-bright); color: #fff; transform: translateY(-1px); box-shadow: 0 12px 28px -10px var(--red-glow); }
.btn-primary .icon-arrow { transition: transform var(--dur) var(--ease); }
.btn-primary:hover .icon-arrow { transform: translateX(3px); }
.btn-outline { border-color: var(--red); color: var(--text); background: rgba(9, 9, 11, 0.4); }
.btn-outline:hover, .btn-outline:focus-visible { background: var(--red-soft); border-color: var(--red-bright); color: #fff; transform: translateY(-1px); }
.btn-ghost { border-color: var(--border); color: var(--text); background: var(--surface); }
.btn-ghost:hover, .btn-ghost:focus-visible { border-color: var(--border-strong); background: var(--surface-hover); }
.btn-sm { min-height: 40px; padding: 0.5rem 1rem; font-size: 0.875rem; }
.btn-block { width: 100%; }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  display: flex; align-items: flex-start;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
  margin-top: calc(-1 * var(--header-h));
}
/* Artwork layer: a real <picture>, painted first (z-index 0) with the copy above it (z-index 1).
   No negative z-index and no viewport units, so snapshot/full-page renderers keep it.
   The box (.hero__art) is the only thing that has a size; picture and img are pinned to its
   edges with inset:0 rather than percentage heights, which WebKit resolves against the
   unclamped aspect-ratio height and lets the image overflow the box on wide phones. */
.hero__art { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hero__art picture { position: absolute; inset: 0; display: block; }
.hero__art img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; object-position: 58% 32%; }
.hero__inner { position: relative; z-index: 1; }
.hero__shade {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(9, 9, 11, 0.92) 0%, rgba(9, 9, 11, 0.82) 26%, rgba(9, 9, 11, 0.45) 46%, rgba(9, 9, 11, 0.08) 66%, rgba(9, 9, 11, 0) 100%),
    linear-gradient(180deg, rgba(9, 9, 11, 0.55) 0%, rgba(9, 9, 11, 0) 24%, rgba(9, 9, 11, 0) 72%, rgba(9, 9, 11, 0.85) 100%);
}
.hero__inner { padding-top: 1.75rem; padding-bottom: clamp(2rem, 3vw, 2.75rem); width: 100%; }
.hero__content { max-width: 560px; }
.hero__greeting { font-family: var(--font-mono); color: var(--red-text); font-size: 0.95rem; margin: 0 0 var(--space-2); }
.hero__title {
  font-size: clamp(2.6rem, 4.9vw, 4.25rem); font-weight: 800; letter-spacing: -0.035em; line-height: 0.98;
  margin: 0 0 var(--space-4);
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.6);
}
.hero__title .cursor { width: 5px; height: 0.82em; vertical-align: -0.05em; margin-left: 0.06em; }
/* Name flourish: the invisible sizer keeps the two-line block size while the live layer is retyped on top,
   so nothing below ever moves. The screen-reader name is the static text before it. */
.hero__name { position: relative; display: block; }
.hero__name-sizer { visibility: hidden; }
.hero__name-live { position: absolute; inset: 0; white-space: nowrap; }
.hero__name-live .cursor.is-typing { animation: none; visibility: visible; }
.hero__lead {
  font-family: var(--font-mono); font-size: clamp(0.9rem, 1.05vw, 0.98rem); line-height: 1.65;
  color: var(--text-muted); max-width: 46ch; margin: 0 0 var(--space-5);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-5); }
@media (max-width: 1080px) and (min-width: 861px) {
  /* nav sits closer to the copy on narrow desktops: start the hero copy under it */
  .hero__inner { padding-top: calc(var(--header-h) + 0.5rem); }
}
.hero__traits { list-style: none; display: flex; flex-wrap: wrap; gap: 0.75rem 1.5rem; font-size: 0.85rem; color: var(--text-muted); }
.hero__traits li { display: inline-flex; align-items: center; gap: 0.5rem; }
.hero__traits .icon { width: 1.1rem; height: 1.1rem; color: var(--text); opacity: 0.9; }

@media (max-width: 860px) {
  /* Mobile: the artwork is an in-flow box with a fixed aspect ratio (stable height, no CLS),
     and the copy overlaps its lower part. Nothing depends on the viewport height. */
  .hero { display: block; }
  .hero__art { position: relative; inset: auto; width: 100%; aspect-ratio: 4 / 5; max-height: 32rem; }
  /* Mobile source is a 1:1 crop; cover trims the sides and object-position frames the subject
     slightly right of centre so the laptop stays in shot at every phone width. */
  .hero__art img { object-position: 58% 50%; }
  .hero__shade {
    background:
      linear-gradient(180deg, rgba(9, 9, 11, 0.45) 0%, rgba(9, 9, 11, 0.05) 16%, rgba(9, 9, 11, 0.15) 45%, rgba(9, 9, 11, 0.85) 78%, var(--background) 100%);
  }
  .hero__inner { margin-top: -11rem; padding-top: 0; padding-bottom: var(--space-6); }
  .hero__content { max-width: 100%; }
  .hero__actions .btn { flex: 1 1 auto; }
  .hero__traits { gap: 0.6rem 1.2rem; font-size: 0.8rem; }
}
@media (max-width: 420px) {
  .hero__actions .btn { flex: 1 1 100%; }
}

/* ---------- Cards ---------- */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
.card.is-link:hover, .card.is-link:focus-within {
  transform: translateY(-3px);
  border-color: var(--border-strong);
  background: var(--surface-2);
  box-shadow: var(--shadow-lift), 0 0 0 1px rgba(229, 25, 43, 0.2), 0 0 40px -18px var(--red-glow);
}
.card__body { padding: var(--space-5); display: flex; flex-direction: column; gap: 0.6rem; flex: 1; }
.card__title { font-size: 1.35rem; font-weight: 700; letter-spacing: -0.02em; }
.card__title--mono { font-family: var(--font-mono); font-size: 1.3rem; letter-spacing: -0.01em; }
.card__title a { display: inline-block; padding: 0.15rem 0; margin: -0.15rem 0; }
.card__desc { color: var(--text-muted); font-size: 0.95rem; line-height: 1.55; margin: 0; flex: 1; }
.card__foot {
  margin-top: var(--space-3); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  font-size: 0.9rem; font-weight: 600;
}
.card__foot .icon { width: 1rem; height: 1rem; color: var(--red-text); transition: transform var(--dur) var(--ease); }
.card.is-link:hover .card__foot .icon-arrow { transform: translateX(3px); }
.card.is-link:hover .card__foot .icon-external { transform: translate(2px, -2px); }
.card__link { color: var(--red-text); }
.card__foot > a, .card__foot > span { display: inline-flex; align-items: center; gap: 0.4rem; min-height: 24px; padding: 0.15rem 0; }
.card__link--muted { color: var(--text-muted); font-weight: 500; display: inline-flex; align-items: center; gap: 0.4rem; }
.card__link--muted .icon { color: var(--text-dim); }
/* whole card clickable via stretched link */
.card .stretched::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.card .stretched:focus-visible { outline: none; }
.card:has(.stretched:focus-visible) { outline: 2px solid var(--focus); outline-offset: 3px; }
.card.is-link { cursor: pointer; }
/* Secondary "more about" control: its own link, layered above the stretched link */
.card__info {
  position: absolute; top: 0.75rem; left: 0.75rem; z-index: 2;
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(9, 9, 11, 0.62); color: var(--text-muted); border: 1px solid rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.card__info .icon { width: 1rem; height: 1rem; }
.card__info:hover, .card__info:focus-visible { color: #fff; background: rgba(9, 9, 11, 0.85); border-color: var(--red-bright); }
.card--compact .card__info { top: 0.85rem; right: 0.85rem; left: auto; }

.card__media {
  aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
}
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease), filter 600ms var(--ease); }
.card.is-link:hover .card__media img { transform: scale(1.04); }

.card--compact .card__body { gap: 0.75rem; }
.card--compact .card__head { display: flex; align-items: center; gap: 0.85rem; }
.card--compact .card__title { font-size: 1.15rem; }
.card__icon {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: var(--red-soft); color: var(--red-text);
}
.card__icon .icon { width: 22px; height: 22px; }
/* Official third-party logos: the artwork is never modified.
   Full lockups sit on a white tile (they are designed for light backgrounds);
   the circular hallmark sits directly on the card inside a white ring. */
.brand-tile { display: inline-flex; align-items: center; justify-content: center; background: #fff; border-radius: var(--radius-sm); padding: 0.9rem 1.25rem; }
.brand-tile img { width: 100%; max-width: 320px; height: auto; object-fit: contain; }
/* EC hallmark: official artwork untouched, centred on a compact white disc */
.card__icon--hallmark { background: #fff; padding: 6px; }
.card__icon--hallmark img { width: 100%; height: 100%; object-fit: contain; }
.brand-card { display: grid; gap: 0.75rem; padding: 1rem 1.1rem; text-decoration: none; color: var(--text); }
.brand-card__row { display: flex; align-items: center; gap: 0.85rem; }
.brand-card__name { display: block; font-weight: 700; letter-spacing: -0.01em; }
.brand-card__role { display: block; font-size: 0.85rem; color: var(--text-muted); }
.brand-card__role b { color: var(--text-muted); font-weight: 500; }

.badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 0.25rem 0.55rem; border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong); color: var(--text-muted); background: rgba(9, 9, 11, 0.6);
}
.badge--live { color: #34d399; border-color: rgba(52, 211, 153, 0.35); }
.badge--live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 8px currentColor; }
.badge--red { color: var(--red-bright); border-color: rgba(229, 25, 43, 0.4); }
.badge .icon { width: 0.8rem; height: 0.8rem; }
.card__media .badge { position: absolute; top: 0.75rem; right: 0.75rem; backdrop-filter: blur(6px); }
.card__media { position: relative; }

.tags { list-style: none; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.tags li {
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 0.2rem 0.6rem;
}

/* ---------- Spotify / Now playing ---------- */
.now-playing { padding: clamp(1.25rem, 2.5vw, 1.75rem); }
.now-playing__head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem 1rem; margin-bottom: clamp(1rem, 2vw, 1.5rem); }
.now-playing__state { font-size: 0.85rem; color: var(--text-muted); display: inline-flex; align-items: center; gap: 0.5rem; white-space: nowrap; }
.now-playing__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-dim); flex: 0 0 auto; }
.now-playing[data-state="playing"] .now-playing__dot { background: #1ed760; box-shadow: 0 0 10px #1ed760; animation: pulse 1.6s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: 0.45; } }
.now-playing__row {
  display: grid; grid-template-columns: 96px minmax(0, 1fr); grid-template-areas: "art info";
  gap: 1.25rem 1.5rem; align-items: center;
}
.now-playing__art {
  grid-area: art; display: block; width: 96px; height: 96px; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2);
  border: 1px solid var(--border); position: relative; align-self: center;
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.now-playing__art img { width: 100%; height: 100%; object-fit: cover; }
.now-playing__art > .icon-music { position: absolute; inset: 0; margin: auto; width: 30px; height: 30px; color: var(--text-dim); }
.now-playing__art:has(img) > .icon-music { display: none; }
/* Artwork is the link: a quiet play glyph appears on hover / focus only */
a.now-playing__art { cursor: pointer; }
a.now-playing__art:hover, a.now-playing__art:focus-visible { transform: scale(1.03); border-color: #1ed760; box-shadow: 0 0 0 1px rgba(30, 215, 96, 0.35), 0 10px 30px -12px rgba(0, 0, 0, 0.8); }
a.now-playing__art:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.now-playing__art-play {
  position: absolute; inset: 0; display: grid; place-items: center; background: rgba(9, 9, 11, 0.45);
  opacity: 0; transition: opacity var(--dur) var(--ease);
}
.now-playing__art-play .icon { width: 26px; height: 26px; color: #fff; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6)); }
a.now-playing__art:hover .now-playing__art-play, a.now-playing__art:focus-visible .now-playing__art-play { opacity: 1; }
.now-playing__info { grid-area: info; min-width: 0; display: grid; gap: 0.3rem; align-content: center; }
.now-playing__brand { width: 1.15rem; height: 1.15rem; color: #1ed760; flex: 0 0 auto; }
.now-playing__track { font-weight: 700; font-size: 1.1rem; line-height: 1.3; letter-spacing: -0.01em; display: flex; align-items: flex-start; gap: 0.55rem; min-width: 0; margin: 0; }
.now-playing__track .now-playing__brand { margin-top: 0.15em; }
.now-playing__track span { min-width: 0; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2; }
.now-playing__artist { color: var(--text-muted); font-size: 0.92rem; line-height: 1.4; margin: 0; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2; }
.now-playing__progress { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; margin-top: 0.5rem; }
.now-playing__bar { height: 4px; background: var(--border-strong); border-radius: 2px; overflow: hidden; }
.now-playing__fill { height: 100%; width: var(--p, 0%); background: linear-gradient(90deg, var(--red-deep), var(--red-bright)); border-radius: 2px; transition: width 1s linear; }
.now-playing__time { font-family: var(--font-mono); font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.now-playing[data-state="fallback"] .now-playing__progress, .now-playing[data-state="idle"] .now-playing__progress, .now-playing[data-state="recent"] .now-playing__progress { display: none; }
.now-playing__note { font-size: 0.78rem; color: var(--text-dim); margin: 0.35rem 0 0; }
@media (max-width: 860px) {
  .now-playing__row { grid-template-columns: 84px minmax(0, 1fr); gap: 1rem; }
  .now-playing__art { width: 84px; height: 84px; }
  .now-playing__track { font-size: 1.02rem; }
  .now-playing__track span { -webkit-line-clamp: 3; line-clamp: 3; }
}

/* ---------- Footer ---------- */
.site-footer { border-top: 1px solid var(--border); margin-top: var(--space-7); background: linear-gradient(180deg, var(--background), #07070a); }
.site-footer__inner {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--space-5); align-items: center;
  padding-block: var(--space-6);
}
.site-footer__tag { color: var(--text-muted); font-size: 0.9rem; margin: 0; }
.site-footer__social { list-style: none; display: flex; gap: 0.5rem; justify-content: center; }
.site-footer__social a {
  width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
  border: 1px solid var(--border); color: var(--text-muted);
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.site-footer__social a:hover, .site-footer__social a:focus-visible { color: var(--text); border-color: var(--border-strong); transform: translateY(-2px); }
.site-footer__social .icon { width: 1.05rem; height: 1.05rem; }
.site-footer__quote { text-align: right; font-size: 0.85rem; color: var(--text-muted); font-style: italic; margin: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem; }
.site-footer__dash { width: 18px; height: 2px; background: var(--red); display: block; }
.site-footer__meta {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--space-4);
  padding-block: var(--space-4); border-top: 1px solid var(--border);
  font-size: 0.75rem; color: var(--text-dim);
}
.site-footer__nav { display: flex; flex-wrap: wrap; gap: 0 1.1rem; justify-content: center; color: var(--text-muted); }
.site-footer__nav a { display: inline-block; padding: 0.4rem 0; }
.site-footer__nav a:hover { color: var(--text); }
.site-footer__hint { color: var(--text-dim); text-align: right; }
.site-footer__hint .cursor { background: var(--text-dim); height: 0.9em; }
@media (max-width: 860px) {
  .site-footer__inner, .site-footer__meta { grid-template-columns: 1fr; gap: var(--space-4); }
  .site-footer__social { justify-content: flex-start; }
  .site-footer__quote { text-align: left; align-items: flex-start; }
  .site-footer__nav { justify-content: flex-start; }
  .site-footer__hint { text-align: left; }
}

/* ---------- Sly (footer mascot Easter egg) ----------
   A fixed 60x65 box (one 192x208 atlas cell, same aspect) beside the tagline. The box is reserved from first
   paint and stays invisible until assets/js/sly.js has his sprite, so nothing shifts and nothing empty can be focused. */
.site-footer__lead { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
.sly { position: relative; flex: none; visibility: hidden; }
.sly.sly--ready { visibility: visible; }
.sly.sly--failed, .no-js .sly { display: none; }
.sly__btn {
  display: block; width: 60px; height: 65px; border-radius: var(--radius-sm);
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.sly__btn:focus-visible { outline-offset: 2px; }
.sly__canvas { display: block; width: 60px; height: 65px; pointer-events: none; }

.sly-pop {
  position: absolute; left: 0; bottom: calc(100% + 0.6rem); z-index: 45;
  width: min(340px, calc(100vw - 2 * var(--gutter)));
  padding: 0.9rem 1rem 1rem; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--border-strong);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  text-align: left; font-style: normal;
}
.sly-pop[hidden] { display: none; }
.sly-pop:focus { outline: none; }
.sly-pop--below { bottom: auto; top: calc(100% + 0.6rem); }
/* Phones (and any screen where it will not fit beside him): pinned to the bottom of the viewport, always
   fully reachable, scrolling inside itself if the screen is short. The page underneath never moves. */
.sly-pop--sheet {
  position: fixed; top: auto; left: var(--gutter); right: var(--gutter);
  bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  width: auto; max-width: 420px; margin-inline: auto;
  max-height: calc(100vh - 5.5rem); max-height: calc(100dvh - 5.5rem);
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
.sly-pop__bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.35rem; }
.sly-pop__title { margin: 0; font-size: 0.8rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); }
.sly-pop__title::before { content: "> "; color: var(--red-text); }
.sly-pop__close { width: 40px; height: 40px; margin: -0.35rem -0.4rem -0.35rem 0; border-radius: 50%; display: grid; place-items: center; color: var(--text-muted); border: 1px solid var(--border); background: var(--surface-2); transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.sly-pop__close .icon { width: 0.95rem; height: 0.95rem; }
.sly-pop__close:hover, .sly-pop__close:focus-visible { border-color: var(--red-bright); color: var(--red-bright); }
.sly-pop__intro { margin: 0 0 0.75rem; font-size: 0.92rem; color: var(--text); }
/* The stage is wider than Sly so the scuttle stays inside it; the canvas only ever moves sideways. */
.sly-pop__stage {
  position: relative; display: grid; place-items: center; height: 120px; overflow: hidden;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: radial-gradient(ellipse 60% 55% at 50% 100%, var(--red-soft), transparent 70%), var(--background);
}
.sly-pop__canvas { display: block; width: 96px; height: 104px; }
.sly-pop__caption { min-height: 1.5em; margin: 0.45rem 0 0.6rem; font-size: 0.75rem; color: var(--text-dim); text-align: center; }
.sly-pop__actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.4rem; margin-bottom: 0.85rem; }
.sly-pop__actions[hidden] { display: none; }
.sly-pop__action {
  min-height: 40px; padding: 0.4rem 0.5rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-muted);
  font-size: 0.78rem; font-weight: 500;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.sly-pop__action:hover, .sly-pop__action:focus-visible { color: var(--text); border-color: var(--border-strong); background: var(--surface-hover); }
.sly-pop__action:active { border-color: var(--red); }
.sly-pop__still { margin: 0 0 0.85rem; font-size: 0.8rem; color: var(--text-dim); }
.sly-pop__links { display: grid; gap: 0.5rem; }
.sly-pop__links .btn { white-space: normal; text-align: center; }
.sly-pop__links .btn[aria-busy="true"] { cursor: progress; opacity: 0.75; }
.sly-pop__status { min-height: 1.4em; margin: 0.6rem 0 0; font-size: 0.78rem; color: var(--text-muted); }

/* ---------- Inner page header ---------- */
.page-head { padding-top: clamp(2.5rem, 6vw, 4.5rem); padding-bottom: clamp(1.5rem, 4vw, 2.5rem); }
.page-head__title { font-size: clamp(2.2rem, 5.5vw, 3.5rem); font-weight: 800; letter-spacing: -0.035em; margin: 0.25rem 0 var(--space-4); }
.page-head__lead { font-size: clamp(1.05rem, 1.4vw, 1.2rem); color: var(--text-muted); max-width: 62ch; margin: 0; }
.page-head--center { text-align: center; }
.page-head--center .page-head__lead { margin-inline: auto; }

/* ---------- Project detail ---------- */
.project-hero { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.project-hero__media { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.project-hero__media img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
/* Brand-only projects (day job): compact hallmark panel instead of a 16:9 media tile */
.brand-panel {
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow);
  padding: clamp(1.5rem, 4vw, 2.5rem); display: grid; justify-items: center; text-align: center; gap: 0.25rem; align-self: start;
}
.brand-panel__mark { width: 96px; height: 96px; margin-bottom: 0.75rem; }
.brand-panel__mark.card__icon--hallmark { padding: 12px; }
.brand-panel__mark .icon { width: 44px; height: 44px; }
.brand-panel__name { margin: 0; font-weight: 700; font-size: 1.2rem; letter-spacing: -0.01em; }
.brand-panel__role { margin: 0; color: var(--text-muted); font-size: 0.9rem; }
.project-meta { display: grid; gap: var(--space-4); }
.project-meta dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.5rem 1.25rem; margin: 0; font-size: 0.95rem; }
.project-meta dt { font-family: var(--font-mono); color: var(--text-dim); font-size: 0.8rem; padding-top: 0.15rem; }
.project-meta dd { margin: 0; }
.project-meta dd a { display: inline-flex; align-items: center; gap: 0.35rem; }
.project-meta dd .icon { width: 1rem; height: 1rem; }
.prose { max-width: 68ch; font-size: 1.05rem; color: var(--text-muted); line-height: 1.75; }
.prose p { margin-bottom: 1.2em; }
.prose > :last-child { margin-bottom: 0; }
.prose strong { color: var(--text); }
.prose a { color: var(--red-text); text-decoration: underline; text-underline-offset: 3px; display: inline-block; padding: 0.15rem 0; margin: -0.15rem 0; }
.prose a:hover { color: #ff6b75; }
.project-nav { display: flex; justify-content: space-between; gap: var(--space-4); margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid var(--border); }
.project-nav a { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--text-muted); font-weight: 500; }
.project-nav a:hover { color: var(--text); }
.project-nav .icon { width: 1rem; height: 1rem; color: var(--red); }
.project-nav__prev .icon { transform: rotate(180deg); }
@media (max-width: 860px) { .project-hero { grid-template-columns: 1fr; } }

/* ---------- Toolbox ---------- */
.tool-card .card__body { gap: 0.5rem; }
.tool-card__emoji { font-size: 1.75rem; line-height: 1; display: block; margin-bottom: 0.35rem; }
.tool-card .card__title { font-size: 1.1rem; }
.tool-card__tagline { margin: -0.35rem 0 0; font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.02em; color: var(--red-text); }
.tool-card .card__foot { margin-top: var(--space-2); }
.toolbox-mark { display: inline-grid; place-items: center; width: 64px; height: 64px; border-radius: var(--radius); background: var(--red-soft); color: var(--red-text); margin-bottom: var(--space-4); }
.toolbox-mark .icon { width: 32px; height: 32px; }

/* ---------- Strolls ---------- */
.walk-list { display: grid; gap: var(--space-5); }
.walk {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 0;
  overflow: hidden;
}
.walk__media { position: relative; min-height: 260px; background: var(--surface-2); }
.walk__media img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; }
.walk__body { padding: var(--space-5) var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); }
.walk__date { font-family: var(--font-mono); font-size: 0.8rem; color: var(--red-text); display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0; }
.walk__date .icon { width: 1rem; height: 1rem; flex: 0 0 auto; }
.walk__title { font-size: 1.5rem; letter-spacing: -0.02em; }
.walk__stats { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; margin: 0.25rem 0; }
.walk__stats b { white-space: nowrap; }
.walk__stats li { background: var(--background); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.55rem 0.7rem; }
.walk__stats b { display: block; font-family: var(--font-mono); font-size: 0.95rem; font-weight: 700; }
.walk__stats span { font-size: 0.7rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.05em; }
.walk__desc { color: var(--text-muted); font-size: 0.95rem; line-height: 1.65; }
.walk__where { display: flex; align-items: flex-start; gap: 0.5rem; color: var(--text-dim); font-size: 0.85rem; line-height: 1.5; margin: 0; }
.walk__where .icon { width: 0.95rem; height: 0.95rem; flex: 0 0 auto; margin-top: 0.2em; color: var(--red-text); }
.walk__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: auto; padding-top: var(--space-2); }
.walk:nth-child(even) .walk__media { order: 2; }
@media (max-width: 860px) {
  .walk { grid-template-columns: 1fr; }
  .walk__media { min-height: 0; aspect-ratio: 16 / 10; }
  .walk__media img { position: static; aspect-ratio: 16 / 10; }
  .walk:nth-child(even) .walk__media { order: 0; }
  .walk__body { padding: var(--space-5); }
}
/* ---------- About ---------- */
.about { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--space-7); align-items: start; }
.about__aside { display: grid; gap: var(--space-4); position: sticky; top: calc(var(--header-h) + 1.5rem); }
.facts { list-style: none; display: grid; gap: 0.5rem; align-content: start; }
.facts li { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.75rem 0.9rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); font-size: 0.92rem; }
.facts .icon { width: 1.1rem; height: 1.1rem; color: var(--red); flex: 0 0 auto; margin-top: 0.15rem; }
.facts a { color: var(--red-text); display: inline-block; padding: 0.25rem 0; margin: -0.25rem 0; }
.terminal {
  background: var(--code-bg); color: var(--code-text); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
  font-family: var(--font-mono); font-size: 0.85rem; box-shadow: var(--shadow);
}
/* Window chrome: editor tab / Windows Terminal style, no macOS traffic lights */
.terminal__bar { display: flex; align-items: stretch; gap: 0.4rem; padding: 0 0.6rem; border-bottom: 1px solid var(--border); background: var(--code-bg-2); color: var(--text-muted); font-size: 0.75rem; min-height: 36px; }
.terminal__tab {
  display: inline-flex; align-items: center; gap: 0.45rem; padding: 0 0.85rem; color: var(--code-text);
  background: var(--code-bg); border-inline: 1px solid var(--border); position: relative; margin-bottom: -1px;
}
.terminal__tab::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--red); }
.terminal__tab .icon { width: 0.85rem; height: 0.85rem; color: var(--syntax-string); }
.terminal__title { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0 0.3rem; color: var(--text-muted); }
.terminal__title .icon { width: 0.85rem; height: 0.85rem; }
.terminal__bar .terminal__close { margin-left: auto; align-self: center; }
/* Interactive / transcript terminals: a real terminal palette (Windows Terminal "Campbell"),
   separate from the source-code (Dreamweaver) palette used by tommy.json */
.terminal--shell {
  --term-bg: #0c0c0c; --term-fg: #cccccc; --term-dim: #767676; --term-blue: #3b78ff; --term-cyan: #61d6d6;
  --term-green: #16c60c; --term-red: #e74856; --term-yellow: #f9f1a5;
  background: var(--term-bg); color: var(--term-fg);
}
.terminal--shell .terminal__body { color: var(--term-fg); font-size: 0.84rem; line-height: 1.6; }
.terminal--shell .terminal__body b { color: var(--term-fg); }
.terminal--shell .cursor { background: var(--term-fg); }
.tm-prompt { color: var(--term-fg); }
.tm-yellow { color: var(--term-yellow); }
.tm-cyan { color: var(--term-cyan); }
.tm-blue { color: var(--term-blue); }
.tm-green { color: var(--term-green); }
.tm-red { color: var(--term-red); }
.tm-dim { color: var(--term-dim); }
.terminal__body { padding: 1rem 1.1rem; line-height: 1.75; color: var(--code-text); overflow-x: auto; }
.terminal__body b { font-weight: 600; }
.terminal__body b:not([class]) { color: var(--code-text); }
.terminal .cursor { background: var(--code-text); }

/* Syntax classes (code surfaces only) */
.sx-keyword { color: var(--syntax-keyword); }
.sx-string { color: var(--syntax-string); }
.sx-number { color: var(--syntax-number); }
.sx-function { color: var(--syntax-function); }
.sx-identifier { color: var(--syntax-identifier); }
.sx-constant { color: var(--syntax-constant); }
.sx-member { color: var(--syntax-member); }
.sx-tag { color: var(--syntax-tag); }
.sx-attr { color: var(--syntax-attr); }
.sx-prompt, .sx-php { color: var(--syntax-php-tag); }
.sx-comment { color: var(--syntax-comment); font-style: italic; }
.sx-error { color: var(--syntax-error); }
@media (max-width: 860px) {
  .about { grid-template-columns: 1fr; gap: var(--space-7); }
  .about__aside { position: static; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); align-items: start; }
}

/* ---------- 404 ---------- */
.notfound { min-height: calc(100dvh - var(--header-h) - 200px); display: grid; place-items: center; text-align: center; padding-block: var(--space-8); }
.notfound__code { font-family: var(--font-mono); font-size: clamp(5rem, 22vw, 11rem); font-weight: 700; line-height: 0.9; letter-spacing: -0.06em; color: var(--red); text-shadow: 0 0 40px var(--red-glow); margin: 0; }
.notfound__code span { color: var(--text); }
.notfound .terminal { text-align: left; max-width: 560px; width: 100%; margin: var(--space-5) auto; }
.notfound__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; }

/* ---------- Hidden terminal (Easter egg) ---------- */
.egg-terminal {
  position: fixed; left: 50%; bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%) translateY(10px);
  width: min(600px, calc(100vw - 2rem)); z-index: 60;
  opacity: 0; visibility: hidden; transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility 0s linear var(--dur);
}
.egg-terminal.is-open { opacity: 1; visibility: visible; transform: translateX(-50%); transition-delay: 0s; }
.egg-terminal .terminal { box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.9), 0 0 0 1px var(--border-strong); }
.egg-terminal__log { height: min(260px, 40dvh); overflow-y: auto; overscroll-behavior: contain; }
.egg-terminal__form { display: flex; flex-wrap: wrap; gap: 0.25rem 0.5rem; align-items: center; padding: 0.55rem 1.1rem; border-top: 1px solid var(--border); background: var(--term-bg); color: var(--term-fg); font-family: var(--font-mono); font-size: 0.84rem; }
.egg-terminal__form .tm-prompt { white-space: nowrap; }
.egg-terminal__form input { flex: 1 1 10ch; background: none; border: 0; color: var(--term-fg); font: inherit; outline: none; min-width: 0; caret-color: var(--term-fg); }
.egg-terminal__form input::placeholder { color: var(--term-dim); }
.egg-terminal__log div { white-space: pre-wrap; overflow-wrap: anywhere; }
/* PuTTY-style session: black window, plain grey text, the classic xterm colours */
.terminal--putty {
  --term-bg: #000000; --term-fg: #bfbfbf; --term-dim: #7a7a7a; --term-blue: #7f95ff; --term-cyan: #55cccc;
  --term-green: #55d955; --term-red: #ff6b6b; --term-yellow: #e6d36a;
}
.terminal--putty .terminal__bar { background: #1b1b1b; border-bottom-color: #2a2a2a; color: #d0d0d0; }
.terminal--putty .terminal__title { color: #d0d0d0; }
.terminal--putty .egg-terminal__form { border-top-color: #1f1f1f; }
.terminal--putty .egg-terminal__log, .terminal--putty .egg-terminal__form { line-height: 1.5; }
/* nano-style editor inside the terminal */
.egg-editor { display: flex; flex-direction: column; background: var(--term-bg); color: var(--term-fg); font-family: var(--font-mono); font-size: 0.84rem; }
.egg-editor[hidden], .egg-terminal__log[hidden], .egg-terminal__form[hidden] { display: none; }
.egg-editor__head { padding: 0.35rem 1.1rem; background: #bfbfbf; color: #000; font-weight: 600; }
.egg-editor__text { display: block; width: 100%; height: min(260px, 40dvh); resize: none; border: 0; outline: none; padding: 0.75rem 1.1rem; background: var(--term-bg); color: var(--term-fg); font: inherit; line-height: 1.5; caret-color: var(--term-fg); white-space: pre; overflow: auto; }
.egg-editor__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; padding: 0.5rem 1.1rem; border-top: 1px solid #1f1f1f; }
.egg-editor__foot .btn { min-height: 36px; }
.egg-editor__hint { color: var(--term-dim); font-size: 0.75rem; margin-left: auto; }
@media (max-width: 860px) {
  /* Phones: anchor to the top so the on-screen keyboard never covers the close button or the prompt. */
  .egg-terminal {
    left: 0.5rem; right: 0.5rem; bottom: auto; top: calc(0.5rem + env(safe-area-inset-top, 0px));
    width: auto; transform: translateY(-6px);
  }
  .egg-terminal.is-open { transform: none; }
  .egg-terminal .terminal__bar { min-height: 32px; }
  .egg-terminal__log { height: min(220px, 32dvh); padding: 0.75rem 0.9rem; font-size: 0.8rem; }
  .egg-terminal__form { padding: 0.5rem 0.9rem; }
  .egg-editor__text { height: min(220px, 32dvh); font-size: max(16px, 1rem); padding: 0.6rem 0.9rem; }
  .egg-editor__head, .egg-editor__foot { padding-inline: 0.9rem; }
  .egg-editor__hint { display: none; }
}
.egg-terminal__close { color: var(--text-muted); display: inline-flex; padding: 0.25rem; border-radius: 4px; }
.egg-terminal__close:hover { color: var(--text); }
.egg-terminal__close .icon { width: 1rem; height: 1rem; }

/* ---------- Motion ---------- */
/* Motion: no scroll-triggered reveals. Content is always rendered at full
   opacity so static captures, crawlers and assistive tech see everything.
   The hero copy gets a single, short entrance on load. */
@media (prefers-reduced-motion: no-preference) {
  .hero__content > * { animation: rise-in 600ms var(--ease) both; }
  .hero__content > *:nth-child(2) { animation-delay: 60ms; }
  .hero__content > *:nth-child(3) { animation-delay: 120ms; }
  .hero__content > *:nth-child(4) { animation-delay: 180ms; }
  .hero__content > *:nth-child(5) { animation-delay: 240ms; }
}
@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
.konami body, body.konami { animation: konami-flash 900ms ease-out; }
@keyframes konami-flash { 0% { filter: hue-rotate(0) saturate(1); } 30% { filter: hue-rotate(160deg) saturate(2); } 100% { filter: none; } }

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

/* ---------- Print ---------- */
@media print {
  .grain, .site-header, .site-footer__meta, .egg-terminal, .sly { display: none; }
  body { background: #fff; color: #000; }
}

/* ---------- Elsewhere lately (photos) ---------- */
.lately { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.lately__heading { color: inherit; display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0; margin: -0.25rem 0; }
.lately__heading .icon { width: 0.8rem; height: 0.8rem; color: var(--text-dim); transition: color var(--dur) var(--ease), transform var(--dur) var(--ease); }
.lately__heading:hover .icon { color: var(--red-text); transform: translate(2px, -2px); }
.lately__grid { list-style: none; display: grid; gap: 0.75rem; }
.lately--aside .lately__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; flex: 1; }
.lately--strip .lately__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
.lately__item {
  position: relative; display: block; height: 100%; min-height: 170px; aspect-ratio: 3 / 4; overflow: hidden;
  border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface);
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.lately--aside .lately__item { aspect-ratio: auto; }
.lately__item img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease); }
.lately__item:hover, .lately__item:focus-visible { transform: translateY(-3px); border-color: var(--border-strong); box-shadow: var(--shadow-lift), 0 0 40px -18px var(--red-glow); }
.lately__item:hover img { transform: scale(1.04); }
@media (max-width: 1080px) {
  .lately--aside .lately__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: auto; }
  .lately--aside .lately__item { aspect-ratio: 3 / 4; height: auto; }
}
@media (max-width: 640px) {
  /* Swipe strip: the scroll surface bleeds to the viewport edges (negative gutter margins) while
     internal padding + scroll-padding keep the first/last tiles on the page gutter at rest and at
     the snap points. Photos travel under the gutter while swiping instead of being clipped. */
  .lately { min-width: 0; }
  .lately__grid, .lately--aside .lately__grid {
    display: flex; gap: 0.75rem; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
    margin-inline: calc(-1 * var(--gutter)); padding: 0.25rem 0 0.75rem var(--gutter);
    scroll-padding-inline: var(--gutter); scrollbar-width: none;
  }
  /* Trailing gutter as a flex spacer (Safari ignores trailing padding in scroll containers); the
     flex gap supplies 0.75rem of it, the spacer the rest, so the last tile ends on the page gutter. */
  .lately__grid::after { content: ""; flex: 0 0 calc(var(--gutter) - 0.75rem); }
  .lately__grid::-webkit-scrollbar { display: none; }
  .lately__grid li { flex: 0 0 min(58%, 240px); scroll-snap-align: start; }
}

/* ---------- Instagram glimpses on About ---------- */
.snap { margin: 0; display: grid; gap: 0.5rem; min-width: 0; }
.snap__link {
  position: relative; display: block; aspect-ratio: 4 / 5; overflow: hidden;
  border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface);
  transition: transform var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.snap__link img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease); }
.snap__link:hover, .snap__link:focus-visible { transform: translateY(-2px); border-color: var(--border-strong); box-shadow: var(--shadow-lift); }
.snap__link:hover img { transform: scale(1.03); }
.snap__mark {
  position: absolute; right: 0.6rem; top: 0.6rem; width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center; color: #fff; background: rgba(9, 9, 11, 0.55); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
}
.snap__mark .icon { width: 0.9rem; height: 0.9rem; }
.snap__caption { font-size: 0.82rem; line-height: 1.45; color: var(--text-muted); padding: 0 0.15rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2; }
.snap--lead .snap__link { aspect-ratio: 4 / 5; }
.snap-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); margin: var(--space-6) 0; }
.snap-row .snap__link { aspect-ratio: 4 / 5; }
@media (max-width: 860px) {
  .about__aside .snap--lead { grid-column: 1 / -1; }
  .about__aside .snap--lead .snap__link { aspect-ratio: 16 / 10; }
}

/* ---------- Project brand accents (from project data, e.g. Localhost #46BAB1) ---------- */
/* Brand marks are official artwork: a sizing box only, no radius, no clipping, no cropping */
.card__mark { width: 24px; height: 24px; display: inline-block; vertical-align: -5px; margin-right: 0.5rem; object-fit: contain; border-radius: 0; }
.page-head__mark { width: 44px; height: 44px; display: inline-block; vertical-align: -7px; margin-right: 0.6rem; object-fit: contain; border-radius: 0; }
.card--accent .card__link { color: var(--project-accent); }
.card--accent .card__foot .icon { color: var(--project-accent); }
.card--accent .cursor { background: var(--project-accent); }
.card--accent.is-link:hover, .card--accent.is-link:focus-within {
  box-shadow: var(--shadow-lift), 0 0 0 1px color-mix(in srgb, var(--project-accent) 55%, transparent), 0 0 40px -18px color-mix(in srgb, var(--project-accent) 45%, transparent);
}
.card--accent .card__info:hover, .card--accent .card__info:focus-visible { border-color: var(--project-accent); }
.page-head--accent .eyebrow, .page-head--accent .eyebrow a { color: var(--project-accent); }
.page-head--accent .cursor { background: var(--project-accent); }
.has-accent .project-meta dd a { color: var(--project-accent); }
.has-accent .project-hero__media { border-color: color-mix(in srgb, var(--project-accent) 45%, var(--border)); }


/* ---------- Lightbox (native <dialog>) ---------- */
.lightbox { border: 0; padding: 0; background: transparent; max-width: min(96vw, 1100px); max-height: 96dvh; width: auto; overflow: visible; }
.lightbox::backdrop { background: rgba(9, 9, 11, 0.88); backdrop-filter: blur(4px); }
.lightbox__bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0 0 0.6rem; color: var(--text-muted); font-family: var(--font-mono); font-size: 0.8rem; }
.lightbox__title { margin: 0; }
.lightbox__close { width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; color: var(--text); border: 1px solid var(--border-strong); background: var(--surface); }
.lightbox__close .icon { width: 1rem; height: 1rem; }
.lightbox__close:hover, .lightbox__close:focus-visible { border-color: var(--red-bright); color: var(--red-bright); }
.lightbox__body { overflow: auto; max-height: calc(96dvh - 3.5rem); border-radius: var(--radius); border: 1px solid var(--border-strong); background: var(--surface); touch-action: pinch-zoom; }
.lightbox__body img { display: block; width: auto; height: auto; max-width: min(96vw, 1100px); max-height: calc(96dvh - 3.5rem); object-fit: contain; margin: 0 auto; }
html.has-dialog { overflow: hidden; }

/* ---------- Contact ---------- */
.contact { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.contact__form { padding: clamp(1.25rem, 3vw, 2rem); }
.contact__aside { display: grid; gap: var(--space-4); }
.form { display: grid; gap: 1.1rem; }
.form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.field { display: grid; gap: 0.4rem; }
.field label { font-size: 0.9rem; font-weight: 600; }
.field input, .field textarea {
  width: 100%; font: inherit; font-size: 1rem; color: var(--text); background: var(--background);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: 0.75rem 0.9rem; min-height: 48px;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.field textarea { resize: vertical; min-height: 160px; }
.field input:focus-visible, .field textarea:focus-visible { outline: none; border-color: var(--red-bright); box-shadow: 0 0 0 3px var(--red-soft); }
.field [aria-invalid="true"] { border-color: var(--red); }
.field__error { margin: 0; font-size: 0.85rem; color: var(--red-text); }
.form__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
.form__note { margin: 0; font-size: 0.8rem; color: var(--text-dim); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.notice { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.9rem 1rem; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-2); margin-bottom: 1.25rem; }
.notice p { margin: 0; }
.notice .icon { width: 1.1rem; height: 1.1rem; flex: 0 0 auto; margin-top: 0.15rem; color: var(--text-muted); }
.notice--ok { border-color: rgba(52, 211, 153, 0.4); }
.notice--ok .icon { color: #34d399; }
.notice--err { border-color: rgba(229, 25, 43, 0.5); }
.notice--err .icon { color: var(--red-text); }
.contact__localhost { padding: 1.25rem; display: grid; gap: 0.6rem; text-decoration: none; color: var(--text); }
.contact__localhost:hover, .contact__localhost:focus-visible { border-color: color-mix(in srgb, var(--project-accent) 55%, var(--border)); }
.contact__localhost-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.contact__localhost-mark { width: 40px; height: 40px; object-fit: contain; }
.contact__localhost-title { font-weight: 700; font-size: 1.15rem; letter-spacing: -0.01em; }
.contact__localhost-link { display: inline-flex; align-items: center; gap: 0.35rem; font-weight: 600; margin-top: 0.15rem; }
.contact__localhost-link .icon { width: 0.9em; height: 0.9em; flex: 0 0 auto; }
.contact__localhost-domain { white-space: nowrap; }
.contact__localhost:hover .contact__localhost-link .icon { transform: translate(2px, -2px); transition: transform var(--dur) var(--ease); }
.contact__social { padding: 1.25rem; display: grid; gap: 0.75rem; }
@media (max-width: 860px) {
  .contact { grid-template-columns: 1fr; }
  /* iOS: form controls at 16px+ so focusing a field never zooms the page (pinch zoom stays available) */
  input, textarea, select, .egg-terminal__form input { font-size: max(16px, 1rem); }
}
