/* ============================================================================
   v5.1 homepage — the "cosmic terminal" variant (Figma node 718:2548)
   Dark only. Same shell as v4 (static top bar, 455px left column, right stage
   with two views, both columns scroll on their own) but a new skin:
   - no rails, no column borders, no bar border
   - Manrope for the heading and card titles, Geist Mono for labels, the
     terminal message box and the footer
   - hero: 40px square avatar + a floating terminal box instead of iMessage bubbles
   - dashed logo strip with corner ticks
   - numbered section headers (01 / SELECTED PROJECTS [0.1v]) over a hairline
   - Selected Projects as a 2-column card grid, Availability as a single card
   - stage: 905×600 panels, 8px apart, 4px radius, 40px side padding
   Carried over: split-scroll columns, view switcher, gallery shuffle, marquee.
   ============================================================================ */

* { margin: 0; padding: 0; box-sizing: border-box; }

/* ---------- design tokens (Figma variable set, dark) ---------- */
:root {
  --bg:                #000000;   /* Background/Primary   */
  --bg-secondary:      #2a2a2a;   /* Background/Secondary */
  --content-primary:   #eeeeee;   /* Content/Primary      */
  --content-secondary: #b4b4b4;   /* Content/Secondary    */
  --content-tertiary:  #b4b4b4;   /* Content/Tertiary     */
  --content-contrast:  #000000;   /* Content/Contrast     */
  --border-primary:    #1f1f1f;   /* Border/Primary       */

  /* surfaces */
  --surface:        rgba(255, 255, 255, 0.08);   /* cards, terminal box */
  --surface-hover:  rgba(255, 255, 255, 0.12);
  --thumb:          rgba(209, 209, 209, 0.02);   /* card thumbnail well */
  --thumb-hover:    rgba(255, 255, 255, 0.04);
  --chip-teal:      rgba(13, 255, 224, 0.24);
  --chip-orange:    rgba(240, 161, 69, 0.24);
  --chip-edge:      rgba(255, 255, 255, 0.24);
  --chat-bg:        rgba(42, 42, 42, 0.64);
  --tick:           var(--content-secondary);    /* corner ticks */
  --glyph:          #a8a8a8;
  --brand-composabl: #ffffff;                  /* no brand colours: every mark glows white */
  --brand-mono:      #ffffff;
  --status-green:  #34c759;                      /* Colors/Green */
  --row-hover:     rgba(255, 255, 255, 0.04);
  --glow:          0 2px 4px rgba(255, 255, 255, 0.25);   /* Figma text glow on the terminal lines */
  --holo-glow:     0 0 6px rgba(255, 255, 255, 0.35), 0 2px 4px rgba(255, 255, 255, 0.25);   /* hologram text glow, white only */

  /* client logos are dark artwork — flip them to light grey */
  --logo-filter: grayscale(1) brightness(0) invert(0.88);

  /* geometry */
  --col-left: 455px;
  --bar-h:    64px;
  --pad-x:    24px;
  --stage-x:  40px;
  --cols:     var(--col-left) minmax(0, 1fr);

  /* type */
  --font-body:    "Geist", system-ui, -apple-system, sans-serif;
  --font-display: "Manrope", "Geist", system-ui, -apple-system, sans-serif;
  --font-mono:    "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

html { scroll-behavior: smooth; color-scheme: dark; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--content-primary);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  height: 100dvh;
  overflow: hidden;                /* desktop: the two columns scroll, not the body */
}

a { color: inherit; }
.icon { display: block; flex-shrink: 0; }

/* ---------- animations ---------- */
@keyframes enter-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes marquee-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }

/* ============ page shell ============
   A fixed 100dvh sheet: row 1 is the static top bar, row 2 holds the two
   independently scrolling columns. Both rows share one 2-track template
   (left column | stage) so the switcher lines up with the gallery. */
.page {
  display: grid;
  grid-template-rows: var(--bar-h) minmax(0, 1fr);
  height: 100dvh;
  max-width: 1620px;
  margin: 0 auto;
}
.bar, .body {
  display: grid;
  grid-template-columns: var(--cols);
  min-height: 0;
}

/* hide scrollbars on the scroll columns (they still scroll); no scroll anchoring */
.intro, .stage {
  scrollbar-width: none;
  -ms-overflow-style: none;
  overflow-anchor: none;
}
.intro::-webkit-scrollbar, .stage::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ---------- corner ticks: four 6px L-shapes hugging a box ---------- */
.ticks { position: absolute; inset: 0; pointer-events: none; }
.ticks span {
  position: absolute;
  width: 6px; height: 6px;
  border: 0 solid var(--tick);
}
.ticks span:nth-child(1) { top: 0;    left: 0;  border-top-width: 1px;    border-left-width: 1px; }
.ticks span:nth-child(2) { top: 0;    right: 0; border-top-width: 1px;    border-right-width: 1px; }
.ticks span:nth-child(3) { bottom: 0; left: 0;  border-bottom-width: 1px; border-left-width: 1px; }
.ticks span:nth-child(4) { bottom: 0; right: 0; border-bottom-width: 1px; border-right-width: 1px; }

/* ---------- top bar (64px, no border) ---------- */
.bar-social {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px var(--pad-x) 8px calc(var(--pad-x) - 8px);   /* 32px hit area, icon box lands 20px in */
}
.bar-social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: 6px;
  color: var(--content-secondary);
  opacity: 0.85;
  transition: opacity 0.2s ease, color 0.2s ease, background 0.2s ease;
}
.bar-social a:hover { opacity: 1; color: var(--content-primary); background: var(--row-hover); }

.bar-nav {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 8px var(--stage-x);      /* the switcher sits flush with the gallery's left edge */
}

/* view switcher: a 2px padded tray, the active button is a raised black tab */
.seg {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border-radius: 10px;
  background: var(--bg-secondary);
}
.seg-pill {
  position: absolute;
  top: 2px; left: 0;
  height: 28px;
  width: 0;
  border-radius: 10px;
  background: var(--bg);
  border: 1px solid var(--border-primary);
  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.12);
  pointer-events: none;
  z-index: 0;
}
.seg.is-ready .seg-pill { transition: transform 0.38s cubic-bezier(0.22, 1, 0.36, 1), width 0.38s cubic-bezier(0.22, 1, 0.36, 1); }
.seg-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 28px;
  padding: 4px 8px;
  border: 0;
  border-radius: 100px;
  background: transparent;
  color: var(--content-tertiary);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: -0.084px;
  white-space: nowrap;
  cursor: pointer;
  z-index: 1;
  transition: color 0.2s ease;
}
.seg-btn:hover { color: var(--content-primary); }
.seg-btn.is-active { color: var(--content-primary); font-weight: 500; }
/* reserve the bold width so the label never shifts when the weight changes */
.seg-label { display: inline-grid; }
.seg-label::before {
  content: attr(data-text);
  grid-area: 1 / 1;
  font-weight: 500;
  visibility: hidden;
}
.seg-label > span { grid-area: 1 / 1; }
.seg-btn:focus-visible { outline: 2px solid var(--content-secondary); outline-offset: 2px; }
.seg-short { display: none; }
.seg-btn .icon-claude { color: #fb8c3d; }

/* sound toggle — right end of the bar, mono like the labels */
.snd {
  position: absolute;
  right: var(--stage-x);
  top: 50%;
  transform: translateY(-50%);
  height: 28px;
  padding: 0 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--content-primary);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
}
.snd .dim { color: var(--content-tertiary); }
.snd:hover { background: var(--row-hover); }
.snd[aria-pressed="false"] { color: var(--content-tertiary); }
.snd:focus-visible { outline: 2px solid var(--content-secondary); outline-offset: 2px; }

/* ---------- body: two scroll columns ---------- */
.intro {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: enter-up 0.7s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
.sec { width: 100%; flex-shrink: 0; }

/* ---------- hero ---------- */
.sec-hero {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 74px var(--pad-x) 32px;   /* 148px to the avatar in Figma; 74px of that is the tilted terminal box */
}

/* avatar + floating terminal box. The block reserves the tilted box's full
   bounding height (113px in Figma) so nothing shifts while the lines come in. */
.intro-head { position: relative; width: 100%; height: 114px; }
.avatar {
  position: absolute;
  left: 0; bottom: 0;
  display: block;
  width: 40px; height: 40px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg-secondary);
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* the box is tilted (−4° rotate, −2° skew) and catches light on its top and
   bottom edges; its rotated bounding box sits flush with the avatar's bottom */
.term {
  --tilt: rotate(-4deg) skewX(-2deg);
  position: absolute;
  left: 57px; bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 240px;                 /* short messages still get a card-like box */
  padding: 8px;
  /* a translucent pane, monochrome: light catches the edges, the whole thing glows a little */
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.10) 0%, rgba(255, 255, 255, 0) 24%, rgba(255, 255, 255, 0) 76%, rgba(255, 255, 255, 0.10) 100%),
    var(--surface);
  border-top: 1px solid #ffffff;
  border-bottom: 1px solid #ffffff;
  box-shadow:
    0 0 32px -8px rgba(255, 255, 255, 0.28),
    0 0 1px rgba(255, 255, 255, 0.4),
    inset 0 0 24px -12px rgba(255, 255, 255, 0.28);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  color: var(--content-tertiary);
  white-space: nowrap;
  overflow: hidden;                 /* keeps the CRT sweep inside the box */
  opacity: 0;
  transform: translateY(6px) var(--tilt);
  transform-origin: 50% 50%;
  transition: opacity 0.35s ease, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.term.is-in { opacity: 1; transform: var(--tilt); }
/* projector flicker: brightness drifts by a few percent, irregularly, all the time */
.term.is-in { animation: holo-flicker 5.2s steps(1, end) infinite; }
@keyframes holo-flicker {
  0%, 100% { filter: brightness(1); }
  7%   { filter: brightness(1.06); }
  9%   { filter: brightness(0.96); }
  11%  { filter: brightness(1); }
  38%  { filter: brightness(0.93); }
  40%  { filter: brightness(1.04); }
  42%  { filter: brightness(1); }
  63%  { filter: brightness(1.05); }
  64%  { filter: brightness(1); }
  81%  { filter: brightness(0.95); }
  83%  { filter: brightness(1); }
}
.term-cursor { display: flex; align-items: center; min-height: 16px; font-weight: 500; letter-spacing: 0.08em; }
/* braille spinner: the glyph comes from the system mono fallback, so it gets a fixed slot */
.term-spin {
  display: inline-block;
  width: 1.4ch;
  font-family: ui-monospace, Menlo, "SF Mono", Consolas, monospace;
  letter-spacing: 0;
  color: var(--content-primary);
}
.term-spin-label { margin-left: 0.6ch; letter-spacing: 0.02em; opacity: 0.8; }
/* the dashed rule draws itself from the left once the link is up */
.term-rule {
  font-weight: 400;
  line-height: 4px;
  color: var(--content-tertiary);
  text-shadow: var(--holo-glow);
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.term-rule.is-drawn { clip-path: inset(0 0 0 0); }
.term-line {
  font-weight: 500;
  text-shadow: var(--holo-glow);
  visibility: hidden;
}
.term-line.is-in { visibility: visible; }
.term-line b { font-weight: 500; color: var(--content-primary); }
.term-line--sys b { color: var(--content-tertiary); }     /* system line stays grey, only the messages light up */
/* block caret that follows whatever is being typed (terminal and labels alike) */
.caret {
  display: inline-block;
  margin-left: 1px;
  color: var(--content-primary);
  animation: term-blink 0.9s steps(2, end) infinite;
}
@keyframes term-blink { 50% { opacity: 0; } }
.chip .caret { display: none; }

/* glitch, shared by every mono element: 1px jitter, dimmer, cyan / magenta split.
   The terminal keeps its tilt through --tilt; plain labels fall back to none. */
.is-glitch {
  animation: mono-jitter 0.12s steps(2, end) infinite !important;
  filter: brightness(0.82);
  text-shadow: -1px 0 rgba(0, 255, 224, 0.7), 1px 0 rgba(255, 0, 170, 0.7);
}
@keyframes mono-jitter {
  0%   { transform: translate(1px, 0)    var(--tilt, rotate(0)); }
  50%  { transform: translate(-1px, 1px) var(--tilt, rotate(0)); }
  100% { transform: translate(0, -1px)   var(--tilt, rotate(0)); }
}
[data-mono] { display: inline-block; }                 /* so the jitter transform applies to inline labels */
.sec-head [data-mono], .foot[data-mono], .empty-title[data-mono] { display: block; }
.chip[data-mono] { display: inline-flex; }

/* hologram: faint scanlines over the whole box (::after) and a CRT sweep (::before) */
.term::after {
  content: "";
  position: absolute;
  inset: -3px 0 0;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.22) 0 1px, transparent 1px 3px);
  animation: holo-scan 0.7s linear infinite;      /* the lines drift slowly, like a projection */
}
@keyframes holo-scan { to { transform: translateY(3px); } }
.term::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -14px;
  height: 14px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.14) 60%, rgba(255, 255, 255, 0) 100%);
  opacity: 0;
}
.term.is-sweep::before { animation: term-sweep 0.9s cubic-bezier(0.4, 0, 0.6, 1) both; }
@keyframes term-sweep {
  0%   { transform: translateY(0);                 opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateY(calc(100% + 110px)); opacity: 0; }
}
/* the terminal's glitch adds the colour split to its glowing lines too */
.term.is-glitch .term-line,
.term.is-glitch .term-rule,
.term.is-glitch .term-cursor {
  text-shadow: -1px 0 rgba(0, 255, 224, 0.7), 1px 0 rgba(255, 0, 170, 0.7), var(--holo-glow);
}
@media (prefers-reduced-motion: reduce) {
  .term, .term.is-in { opacity: 1; transform: var(--tilt); transition: none; animation: none; }
  .term-line { visibility: visible; }
  .term-rule { clip-path: none; transition: none; }
  .caret, .term::before { display: none; }
  .term::after { animation: none; }
}

/* heading + bio */
.intro-copy { display: flex; flex-direction: column; gap: 24px; width: 100%; margin-top: 32px; }
.intro-title {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 600;
  line-height: 36px;
  letter-spacing: -0.96px;
  color: var(--content-primary);
}
.intro-bio {
  font-size: 14px;
  line-height: 20px;
  letter-spacing: -0.084px;
  color: var(--content-secondary);
}

/* CTA buttons */
.intro-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 32px; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 32px;
  padding: 6px 12px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: -0.084px;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.25s ease, border-color 0.25s ease, opacity 0.2s ease;
}
.btn img { display: block; }
.btn:active { opacity: 0.85; }
.btn--primary {
  background: var(--content-primary);
  color: var(--content-contrast);
  border-color: #ffffff;
  -webkit-backdrop-filter: blur(20px);
          backdrop-filter: blur(20px);
}
.btn--primary:hover { background: #d6d6d6; border-color: #d6d6d6; }   /* white can't get brighter, so it dims a notch */
.btn:active { transform: scale(0.97); }
.btn { transition: background 0.2s ease, border-color 0.2s ease, transform 0.16s ease-out, opacity 0.2s ease; }
.btn--chat {
  background: var(--chat-bg);
  color: var(--content-primary);
  padding-left: 6px;
}
.btn--chat:hover { background: var(--bg-secondary); }
.chat-glyph { width: 20px; height: 20px; border-radius: 1000px; flex-shrink: 0; background: var(--bg-secondary); }

/* ---------- logo strip: 50px dashed box with corner ticks, slow marquee inside ---------- */
.sec-logos { padding: 24px var(--pad-x); }
.logos-box {
  position: relative;
  height: 50px;
  border: 1px dashed var(--border-primary);
}
.logos {
  height: 100%;
  padding: 0 24px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.logos-track {
  display: flex;
  align-items: center;
  height: 100%;
  gap: 32px;
  width: max-content;
  animation: marquee-right 96s linear infinite;   /* one full loop in 96s: barely moving */
}
.logo-box {
  height: 28px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.logo-box img {
  display: block;
  max-width: none;
  filter: var(--logo-filter);
  opacity: 0.85;
  transition: opacity 0.2s ease;
}
.logos:hover .logo-box img { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .logos-track { animation: none !important; } }

/* ---------- numbered section header: 01 / DASHES / TITLE, then a hairline ---------- */
.sec-block { padding: 16px var(--pad-x); }
.sec-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-primary);
  margin-bottom: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 16px;
  white-space: nowrap;
}
.sec-num  { font-weight: 500; color: var(--content-tertiary); }
.sec-dash { font-weight: 400; line-height: 4px; color: var(--border-primary); }
.sec-title { font-size: 12px; line-height: 16px; font-weight: 500; color: var(--content-primary); }   /* h2 reset: Figma is 12px mono */
/* a moment of thinking under a header (braille spinner + label) before the body
   arrives; the line then collapses away — it is not part of the resting layout */
.sec-think { display: none; }
.js-reveal .sec-think {
  display: flex;
  align-items: center;
  height: 16px;
  overflow: hidden;
  transition: height 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}
.js-reveal .sec-think.is-done { height: 0; opacity: 0; }
.sec-title .dim { color: var(--content-tertiary); }

/* ---------- Selected Projects: card grid ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 244px;
  padding: 4px;
  border-radius: 2px;
  background: var(--surface);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}
.card--composabl { --brand: var(--brand-composabl); }
.card--ops, .card--phi { --brand: var(--brand-mono); }
/* hover: the card becomes a small terminal pane — a full-width 1px light along
   the top edge that spills downward into the card, faint scanlines, a soft glow */
.card {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0), 0 0 28px -10px rgba(255, 255, 255, 0);
  transition: background 0.3s ease, box-shadow 0.35s ease;
}
.card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 72px;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0%, rgba(255, 255, 255, 0.05) 40%, rgba(255, 255, 255, 0) 100%);
  opacity: 0;
  transition: opacity 0.35s ease;
}
.card:hover::before, .card:focus-visible::before { opacity: 1; }
.card::after {
  content: "";
  position: absolute;
  inset: -3px 0 0;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.16) 0 1px, transparent 1px 3px);
  opacity: 0;
  transition: opacity 0.35s ease;
}
.card:hover, .card:focus-visible {
  background: var(--surface-hover);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 0 28px -10px rgba(255, 255, 255, 0.22);
  outline: none;
}
.card:hover::after, .card:focus-visible::after { opacity: 1; animation: holo-scan 0.7s linear infinite; }

.card-thumb {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 88px;
  flex-shrink: 0;
  background: var(--thumb);
  transition: background 0.3s ease;
}
.card:hover .card-thumb { background: var(--thumb-hover); }
/* a faint 12px grid behind the mark, fading out towards the edges — the mark sits on a chart */
.card-thumb::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 12px 12px;
  /* a grid line runs through the exact centre, so the 4×4-cell frame lands on lines */
  background-position: calc(50% + 6px) calc(50% + 6px);
  -webkit-mask-image: radial-gradient(ellipse 90% 120% at 50% 50%, #000 30%, transparent 100%);
          mask-image: radial-gradient(ellipse 90% 120% at 50% 50%, #000 30%, transparent 100%);
  opacity: 0.3;                     /* barely there at rest, clearer on hover */
  transition: opacity 0.35s ease;
}
.card:hover .card-thumb::before { opacity: 0.8; }
/* the viewfinder frame from the availability card, shown around the mark on hover */
.card-thumb .frame {
  position: absolute;
  left: calc(50% - 24px); top: calc(50% - 24px);
  width: 49px; height: 49px;         /* 4 cells + the line: both borders sit on grid lines */
  transform: scale(0.82);
  opacity: 0;
  transition: opacity 0.35s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.card:hover .card-thumb .frame { opacity: 1; transform: scale(1); }
/* the mark: flat at rest. On hover it grows and turns in real 3D — JS stacks a
   few copies of the mark behind the front one along Z, so the turn shows a
   solid, darker edge, and the whole block oscillates slowly. */
.card-thumb { perspective: 240px; }
.card-thumb .glyph {
  position: relative;
  display: block;
  width: 72px; height: 72px;
  transform-style: preserve-3d;
  transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.card:hover .card-thumb .glyph { transform: scale(1.35) rotateX(16deg); }
.glyph-spin {
  position: relative;
  display: block;
  width: 100%; height: 100%;
  transform-style: preserve-3d;
}
.card:hover .glyph-spin { animation: glyph-turn 4.2s ease-in-out infinite; }
@keyframes glyph-turn {
  0%, 100% { transform: rotateY(-26deg); }
  50%      { transform: rotateY(26deg); }
}
.card-thumb svg {
  position: absolute;
  inset: 0;
  width: 72px; height: 72px;      /* the sprite glyph is 16px of a 48px box: 72px puts it at 24px */
  display: block;
  overflow: visible;
  fill: var(--glyph);
  transition: fill 0.45s ease, filter 0.45s ease;
}
/* extrusion layers (added by JS): darker, stepped back along Z, only visible when turned */
.card-thumb svg.layer { fill: #5c5c5c; transform: translateZ(calc(var(--z) * -1.2px)); }
.card:hover .card-thumb svg.layer { fill: #8a8a8a; }
.card:hover .card-thumb svg:not(.layer) {
  fill: var(--brand);
  filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.4));
}
@media (prefers-reduced-motion: reduce) {
  .card-thumb svg, .card-thumb .glyph, .card-thumb .frame { transition: none; }
  .card:hover .glyph-spin { animation: none; transform: rotateY(-20deg); }
  .card:hover .card-thumb .glyph { transform: scale(1.2) rotateX(12deg); }
}

.card-body {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1;
  min-height: 0;
  padding: 8px;
}
.card-text { display: flex; flex-direction: column; gap: 6px; }
.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 22px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: -0.096px;
  color: var(--content-primary);
  white-space: nowrap;
}
.card-desc {
  font-size: 14px;
  line-height: 20px;
  letter-spacing: -0.084px;
  color: var(--content-secondary);
  transition: color 0.35s ease;
}
.card:hover .card-desc { color: var(--content-primary); }

/* chip: teal slab with 1px light edges left and right, no radius */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 20px;
  padding: 3px 4px;
  border-left: 1px solid var(--chip-edge);
  border-right: 1px solid var(--chip-edge);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: -0.072px;
  color: var(--content-primary);
  white-space: nowrap;
  align-self: flex-start;
}
.chip--teal   { background: var(--chip-teal); }
.chip--orange { background: var(--chip-orange); }
.chip .icon   { width: 14px; height: 14px; color: #fb8c3d; }      /* Claude orange */

/* ---------- Availability ---------- */
.avail {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 12px;
  border-radius: 4px;
  background: var(--surface);
}
/* signal: a 20px viewfinder of corner ticks with the status dot in the middle */
.finder {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px; height: 20px;
}
.finder .ticks span { transition: border-color 0.25s ease; }
/* every few seconds the dot sends a short burst: two quick blinks, the ticks flash */
.finder.is-ping .status-dot::before { animation: dot-burst 0.7s steps(1, end) both; }
.finder.is-ping .ticks span { border-color: var(--content-primary); }
@keyframes dot-burst {
  0%   { opacity: 1; }
  15%  { opacity: 0.25; }
  30%  { opacity: 1; }
  45%  { opacity: 0.25; }
  60%  { opacity: 1; }
}
/* section bodies wait for their header to finish typing, then rise into place.
   Only when JS is running (html.js-reveal); otherwise everything is visible. */
.js-reveal [data-reveal]:not(.cards) {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.js-reveal [data-reveal]:not(.cards).is-in { opacity: 1; transform: none; }
.js-reveal .cards[data-reveal] .card { opacity: 0; transform: translateY(8px); }
.js-reveal .cards[data-reveal].is-in .card {
  opacity: 1;
  transform: none;
  transition: background 0.3s ease, box-shadow 0.35s ease, opacity 0.45s ease, transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}
.js-reveal .cards[data-reveal].is-in .card:nth-child(2) { transition-delay: 0s, 0s, 90ms, 90ms; }
.js-reveal .cards[data-reveal].is-in .card:nth-child(3) { transition-delay: 0s, 0s, 180ms, 180ms; }

.avail-text { display: flex; flex-direction: column; gap: 6px; }
.avail-title {
  display: flex;
  align-items: center;
  height: 22px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: -0.096px;
  color: var(--content-primary);
}
.avail-note {
  font-size: 14px;
  line-height: 20px;
  letter-spacing: -0.084px;
  color: var(--content-secondary);
}

/* the dot: a 6px green disc (Figma Colors/Green) that breathes and sends out a faint halo */
.status-dot {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 6px; height: 6px;
  flex-shrink: 0;
}
.status-dot::before,
.status-dot::after {
  content: "";
  position: absolute;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--status-green);
}
.status-dot::before { animation: dot-breathe 2.8s ease-in-out infinite; }
.status-dot::after {
  opacity: 0;
  animation: dot-halo 2.8s ease-out infinite;
}
@keyframes dot-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.6; }
}
@keyframes dot-halo {
  0%   { transform: scale(1);   opacity: 0.35; }
  70%  { transform: scale(3); opacity: 0; }
  100% { transform: scale(3); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .status-dot::before, .status-dot::after { animation: none; }
  .status-dot::after { display: none; }
}

/* ---------- footer: [BASIC DATA] in mono under a hairline ---------- */
.sec-footer {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 124px var(--pad-x) 24px;
  margin-top: auto;                 /* pins to the bottom when the column is short */
}
.foot-rule { height: 1px; background: var(--border-primary); }
.foot {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  color: var(--content-tertiary);
  white-space: pre;
}
.foot-dash { font-weight: 400; color: var(--border-primary); }   /* same hairline grey as the section dashes */
.foot a { color: inherit; text-decoration: none; transition: color 0.2s ease; }
.foot a:hover { color: var(--content-primary); }
.foot-social { display: none; }

/* ============ right column — stage with two views ============ */
.stage {
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 8px var(--stage-x) 24px;
}
.view[hidden] { display: none; }
.view { animation: view-in 0.28s ease both; }
@keyframes view-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .view { animation: none; } }

.gallery { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.gallery-group { display: flex; flex-direction: column; gap: 8px; }

/* one panel: 905×600 in Figma, the screenshot covers the frame */
.panel {
  position: relative;
  width: 100%;
  aspect-ratio: 905 / 600;
  border-radius: 4px;
  overflow: hidden;
  background: var(--bg-secondary);
}
.shot-full {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Claude Components — empty state (interactive components land later) */
.empty {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: calc(100dvh - var(--bar-h) - 32px);
  padding: 48px 24px;
  border: 1px dashed var(--border-primary);
  border-radius: 4px;
  text-align: center;
}
.empty-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  margin-bottom: 8px;
  border-radius: 4px;
  background: var(--surface);
  color: #fb8c3d;
}
.empty-title {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  color: var(--content-primary);
}
.empty-title .dim { color: var(--content-tertiary); }
.empty-text {
  max-width: 320px;
  font-size: 14px;
  line-height: 20px;
  letter-spacing: -0.084px;
  color: var(--content-secondary);
}

/* ============ responsive ============ */

/* XL displays: the left column grows so the copy keeps its 407px width */
@media (min-width: 1600px) {
  :root { --pad-x: 40px; --col-left: 487px; }
}

/* smaller laptops: give the stage more room */
@media (min-width: 901px) and (max-width: 1279px) {
  :root { --col-left: 400px; --stage-x: 24px; }
}

/* tablet + phone: one column, normal body scroll, sticky top bar */
@media (max-width: 900px) {
  body { height: auto; overflow: visible; }
  .page { display: block; height: auto; max-width: none; }

  .bar {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    height: var(--bar-h);
    padding: 0 var(--pad-x);
    background: var(--bg);
  }
  .bar-social { padding: 0; margin-left: -8px; }
  .bar-nav { flex: 1; padding: 0; justify-content: flex-end; }
  .snd { position: static; transform: none; margin-right: -8px; }

  .body { display: block; }
  .intro { overflow: visible; animation: none; }
  .sec-hero { padding-top: 56px; }
  .sec-footer { padding-top: 64px; margin-top: 0; }
  /* the stage is moved (JS) into the left column right after Selected Projects:
     switcher on top, then up to four screens; the rest of the gallery is hidden */
  .stage { width: 100%; overflow: visible; padding: 8px var(--pad-x) 16px; }
  .stage-head { display: flex; padding-bottom: 12px; }
  /* full-width switcher, two equal halves; the label keeps its inline-grid so the
     hidden bold copy still only reserves width instead of sitting next to the text */
  .stage-head .seg { margin: 0; width: 100%; }
  .stage-head .seg-btn { flex: 1; justify-content: center; }
  .stage-head .seg-full { display: inline-grid; }
  .stage-head .seg-short { display: none; }
  .sm-hide { display: none; }
  .empty { min-height: 320px; }
}

/* phone */
@media (max-width: 600px) {
  :root { --pad-x: 20px; --bar-h: 56px; }
  .seg-full { display: none; }
  .seg-short { display: inline; }
  .intro-title { font-size: 28px; line-height: 32px; letter-spacing: -0.84px; }
  .sec-hero { padding-top: 40px; }
  .term { font-size: 11px; }
}

/* narrow phones: socials leave the bar and land in the footer, cards stack */
@media (max-width: 480px) {
  /* CTAs keep their natural width, left-aligned */
  .intro-actions { width: auto; }
  .intro-actions .btn { flex: none; }

  /* project cards become rows: an 88px grid square with the mark on the left,
     title / description / chip on the right */
  .cards { grid-template-columns: minmax(0, 1fr); }
  .card { flex-direction: row; height: auto; min-height: 96px; gap: 8px; }
  .card-thumb { width: 88px; height: auto; align-self: stretch; }
  .card-thumb::before { background-position: calc(50% + 6px) calc(50% + 6px); }
  .card-thumb .frame { transform: scale(0.7); }
  .card:hover .card-thumb .frame { transform: scale(0.85); }
  .card-thumb .glyph { transform: scale(0.85); }
  .card:hover .card-thumb .glyph { transform: scale(1.1) rotateX(16deg); }
  .card-body { padding: 8px 8px 8px 4px; gap: 10px; }
  .card-text { gap: 4px; }
  .card-title { height: 20px; }
  .card::before { height: 100%; background: linear-gradient(180deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 60%); }
}
@media (max-width: 380px) {
  .term { left: 48px; font-size: 10px; }
}
