/* ── DESIGN TOKENS ───────────────────────────────── */
:root {
  --bg:        #0e1117;
  --surface:   #141820;
  --surface2:  #1a2030;
  --border:    rgba(255,255,255,0.07);
  --gold:      #e8b44a;
  --gold-dim:  rgba(232,180,74,0.15);
  --teal:      #4ab8c8;
  --teal-dim:  rgba(74,184,200,0.12);
  --text:      #e8e6df;
  --muted:     #7a8494;
  --white:     #ffffff;
  --heading:   #ffffff;

  --f-display: 'Cormorant Garamond', Georgia, serif;
  --f-body:    'Space Grotesk', system-ui, sans-serif;
  --f-mono:    'Space Mono', monospace;
}

/* ── DAY MODE ─────────────────────────────────────
   Night mode (above) is the default. Toggling adds
   .day-mode to <html>, which remaps the same custom
   properties everything else already relies on. ── */
/* ── BLUEPRINT ⇄ AS-BUILT MODE ────────────────────
   Night mode = "Blueprint Phase" (default). Toggling
   adds .day-mode to <html> for the "As-Built Phase":
   finished construction, concrete gray + canvas white.
   Same custom properties everything already relies on. ── */
html.day-mode {
  --bg:        #eef0ee;
  --surface:   #ffffff;
  --surface2:  #e2e5e1;
  --border:    rgba(28,32,28,0.12);
  --gold:      #a97a28;
  --gold-dim:  rgba(169,122,40,0.14);
  --teal:      #12707f;
  --teal-dim:  rgba(18,112,127,0.10);
  --text:      #1c2024;
  --muted:     #667079;
  --white:     #ffffff;
  --heading:   #0e1013;
}

html.day-mode body { -webkit-font-smoothing: antialiased; }
html.day-mode nav { background: rgba(238,240,238,0.85); }
html.day-mode .skill-bar-track { background: rgba(28,32,28,0.08); }
@media (max-width: 768px) {
  html.day-mode .nav-links { background: rgba(238,240,238,0.98); }
}
html.day-mode .cursor-glow { opacity: 0.28; }

/* Sitewide drafting grid — faint cyan gridlines on the blueprint
   background; a subtle structural gray grid once "built". Sits
   behind all content (and behind #bg-particles) via negative z-index. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(74,184,200,0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(74,184,200,0.05) 1px, transparent 1px);
  background-size: 32px 32px;
  transition: background-image 0.4s ease;
}
html.day-mode body::before {
  background-image:
    linear-gradient(rgba(28,32,28,0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(28,32,28,0.045) 1px, transparent 1px);
}

/* Interactive particle-network canvas — drifting nodes linked by
   faint lines, glowing gold near the cursor. Fixed to the viewport
   so it reads as one continuous layer while the page scrolls. */
#bg-particles {
  position: fixed;
  inset: 0;
  z-index: -1;
  display: block;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--f-body);
  font-size: 15px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  overflow-y: hidden; /* unlocked by JS after intro */
}

/* ── INTRO ANIMATION OVERLAY ─────────────────────── */
#intro-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: #050c14;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
#intro-overlay.fade-out {
  transition: opacity 0.5s ease;
  opacity: 0;
  pointer-events: none;
}
#intro-overlay.done {
  display: none;
}

#skip-btn {
  position: absolute;
  top: 20px; right: 28px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: rgba(74,184,200,0.4);
  background: transparent;
  border: 1px solid rgba(74,184,200,0.18);
  padding: 6px 14px;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
  z-index: 10;
}
#skip-btn:hover { color: var(--teal); border-color: var(--teal); }

#stage-label {
  position: absolute;
  top: 22px; left: 28px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: rgba(74,184,200,0.5);
  transition: opacity 0.3s;
}

#intro-progress {
  position: absolute;
  bottom: 0; left: 0;
  height: 2px;
  background: linear-gradient(to right, var(--teal), var(--gold));
  width: 0%;
  transition: width 0.08s linear;
  z-index: 5;
}

/* The wrapper that holds the floor plan SVG during intro */
#intro-fp-wrap {
  width: min(92vw, 860px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
  z-index: 1;
}

.fp-top-label {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(74,184,200,0.5);
}
.fp-bottom-label {
  font-family: var(--f-mono);
  font-size: 8px;
  letter-spacing: 1px;
  color: rgba(74,184,200,0.3);
  text-align: right;
}

/* Name reveal at end. #intro-overlay's background stays a fixed dark
   navy in both themes, so this must not follow the theme-aware
   --heading variable (that flips dark in day mode and would vanish). */
#intro-name {
  position: absolute;
  bottom: 36px;
  font-family: var(--f-display);
  font-size: clamp(22px, 2.8vw, 38px);
  font-weight: 300;
  color: #ffffff;
  letter-spacing: 4px;
  text-transform: uppercase;
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 1.4s cubic-bezier(0.4,0,0.2,1), transform 1.6s cubic-bezier(0.16,1,0.3,1);
  pointer-events: none;
}
#intro-name strong { color: var(--gold); font-weight: 700; }
#intro-name.show { opacity: 1; transform: translateY(0); }

/* Floor plan SVG - groups hidden until JS reveals them */
#fp-svg .fp-frame,
#fp-svg .fp-outer-wall,
#fp-svg .fp-walls-main,
#fp-svg .fp-walls-secondary,
#fp-svg .fp-columns,
#fp-svg .fp-doors,
#fp-svg .fp-windows,
#fp-svg .fp-stairs,
#fp-svg .fp-fixtures,
#fp-svg .fp-dims,
#fp-svg .fp-labels,
#fp-svg .fp-annotations {
  opacity: 0;
}

/* Flowing draw-on: every stroke child gets dashoffset animation */
#fp-svg.drawing-mode line,
#fp-svg.drawing-mode rect,
#fp-svg.drawing-mode polyline,
#fp-svg.drawing-mode polygon,
#fp-svg.drawing-mode path,
#fp-svg.drawing-mode circle,
#fp-svg.drawing-mode ellipse {
  stroke-dasharray: var(--dash-len, 1200);
  stroke-dashoffset: var(--dash-len, 1200);
}
#fp-svg.drawing-mode line.drawn,
#fp-svg.drawing-mode rect.drawn,
#fp-svg.drawing-mode polyline.drawn,
#fp-svg.drawing-mode polygon.drawn,
#fp-svg.drawing-mode path.drawn,
#fp-svg.drawing-mode circle.drawn,
#fp-svg.drawing-mode ellipse.drawn {
  transition: stroke-dashoffset var(--draw-dur, 0.18s) linear;
  stroke-dashoffset: 0;
}

/* When the fp-svg moves into the hero panel */
#fp-svg.in-hero {
  width: 100%;
  height: auto;
  max-height: none;
  display: block;
  filter: drop-shadow(0 12px 40px rgba(74,184,200,0.1));
}

/* ── CURSOR GLOW ─────────────────────────────────── *//* ── CURSOR GLOW ─────────────────────────────────── */
.cursor-glow {
  position: fixed;
  width: 600px;
  height: 600px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(74,184,200,0.04) 0%, transparent 70%);
  pointer-events: none;
  transform: translate(-50%, -50%);
  z-index: 0;
  transition: opacity 0.3s;
}

/* ── NOISE TEXTURE OVERLAY ───────────────────────── */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 999;
  opacity: 0.4;
}

/* ── NAV ─────────────────────────────────────────── */
nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 56px;
  height: 60px;
  background: rgba(14,17,23,0.85);
  backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border);
}

.nav-logo {
  grid-column: 1;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--gold);
  justify-self: start;
}

.nav-links {
  grid-column: 2;
  display: flex;
  gap: 36px;
  list-style: none;
  justify-self: center;
}

.nav-links a {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  transition: color 0.2s;
  position: relative;
}

.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -2px; left: 0;
  width: 0; height: 1px;
  background: var(--teal);
  transition: width 0.3s ease;
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::after { width: 100%; }

.nav-right {
  grid-column: 3;
  display: flex;
  align-items: center;
  gap: 24px;
  justify-self: end;
}

/* ── "Blueprint → As-Built" toggle: SPIRIT LEVEL ────
   Not a switch at all — a surveyor's bubble level, the
   instrument that decides whether something is true.
   Blueprint: the vial sits tilted and the bubble is run
   off to the low end — a reading out of tolerance, work
   not yet verified. Click and the vial rotates level;
   the bubble obeys, rolling toward the etched centre
   window, overshooting, rocking back and settling
   between the marks. As-Built = the reading checks out. ── */
.ce-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  -webkit-tap-highlight-color: transparent;
}

/* Wrapper holds the vial plus the machined body it sits in */
.ce-level {
  position: relative;
  display: block;
  width: 58px;
  height: 30px;
  flex-shrink: 0;
  color: var(--teal);
  transition: color 0.5s ease, transform 0.18s ease;
}
html.day-mode .ce-level { color: var(--gold); }

/* The machined aluminium body the vial is seated in — a thin
   bar under the glass, so the thing reads as a tool and not
   as a UI pill. Stays perfectly horizontal; only the vial tilts. */
.ce-level-base {
  position: absolute;
  left: 1px;
  right: 1px;
  bottom: 0;
  height: 4px;
  border-radius: 1px;
  background: linear-gradient(180deg, rgba(74,184,200,0.35), rgba(74,184,200,0.12));
  transition: background 0.5s ease;
}
html.day-mode .ce-level-base {
  background: linear-gradient(180deg, rgba(169,122,40,0.5), rgba(169,122,40,0.18));
}
/* Machined notches on the body */
.ce-level-base::before,
.ce-level-base::after {
  content: '';
  position: absolute;
  top: -2px;
  width: 1px;
  height: 8px;
  background: currentColor;
  opacity: 0.35;
}
.ce-level-base::before { left: 9px; }
.ce-level-base::after  { right: 9px; }

/* ── THE VIAL ──
   Barrel-shaped glass tube. This is the part that tilts.
   Rotating the vial (not the bubble) is what makes the
   bubble's travel read as gravity rather than as a slider. */
.ce-level-vial {
  position: absolute;
  left: 0;
  top: 1px;
  width: 58px;
  height: 22px;
  border: 1px solid rgba(74,184,200,0.45);
  border-radius: 11px / 9px;
  overflow: hidden;
  transform-origin: 50% 120%;
  transform: rotate(3.2deg);
  box-shadow:
    inset 0 2px 4px rgba(0,0,0,0.45),
    inset 0 -1px 2px rgba(255,255,255,0.06);
  transition:
    transform 0.72s cubic-bezier(.36,1.42,.5,1),
    border-color 0.5s ease,
    box-shadow 0.5s ease;
}
html.day-mode .ce-level-vial {
  transform: rotate(0deg);
  border-color: rgba(169,122,40,0.55);
  box-shadow:
    inset 0 2px 4px rgba(120,90,20,0.18),
    inset 0 -1px 2px rgba(255,255,255,0.7);
}

/* The fluid filling the tube */
.ce-level-fluid {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(74,184,200,0.10) 0%, rgba(74,184,200,0.22) 100%);
  transition: background 0.5s ease;
}
html.day-mode .ce-level-fluid {
  background: linear-gradient(180deg, rgba(232,180,74,0.22) 0%, rgba(169,122,40,0.30) 100%);
}
/* Curved glass highlight running along the top of the tube */
.ce-level-fluid::after {
  content: '';
  position: absolute;
  left: 5px;
  right: 5px;
  top: 2px;
  height: 5px;
  border-radius: 50%;
  background: linear-gradient(180deg, rgba(255,255,255,0.22), rgba(255,255,255,0));
}

/* Graduation marks etched down the length of the vial */
.ce-level-ticks {
  position: absolute;
  inset: 4px 3px;
  background-image: repeating-linear-gradient(
    90deg,
    currentColor 0 1px,
    transparent 1px 7px
  );
  opacity: 0.18;
  transition: opacity 0.5s ease;
}
html.day-mode .ce-level-ticks { opacity: 0.26; }

/* The centre window — the two heavy etched lines a bubble
   must sit between for the reading to count as level. */
.ce-level-window {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 18px;
  transform: translateX(-50%);
  border-left: 1.5px solid rgba(74,184,200,0.5);
  border-right: 1.5px solid rgba(74,184,200,0.5);
  transition: border-color 0.5s ease, box-shadow 0.5s ease;
}
html.day-mode .ce-level-window {
  border-left-color: var(--gold);
  border-right-color: var(--gold);
  box-shadow: 0 0 7px rgba(232,180,74,0.45);
}

/* ── THE BUBBLE ──
   Rolls to whichever end of the tilted vial is raised.
   The overshoot easing gives it the slosh of trapped air:
   it runs past the mark, rocks back, and settles. */
.ce-level-bubble {
  position: absolute;
  top: 50%;
  left: 4px;
  width: 15px;
  height: 15px;
  margin-top: -7.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #eafaff 0%, #a8dfe9 55%, #6bbccd 100%);
  box-shadow:
    0 0 6px rgba(74,184,200,0.75),
    inset 0 -1px 2px rgba(0,0,0,0.18);
  transform: translateX(0);
  transition:
    transform 0.72s cubic-bezier(.36,1.42,.5,1),
    background 0.5s ease,
    box-shadow 0.5s ease;
}
html.day-mode .ce-level-bubble {
  /* Vial comes level, so the bubble settles dead centre, inside the
     window. Inner width 56 ÷ 2 = 28 centre; bubble is 15 wide, so its
     left edge lands at 20.5 — a travel of 16.5px from its 4px rest. */
  transform: translateX(16.5px);
  background: radial-gradient(circle at 35% 30%, #fffdf4 0%, #ffe7ad 55%, #e8b44a 100%);
  box-shadow:
    0 0 8px rgba(232,180,74,0.8),
    inset 0 -1px 2px rgba(120,90,20,0.22);
}

/* Hover / press feedback on the instrument as a whole */
.ce-toggle:hover .ce-level-vial { border-color: var(--teal); }
html.day-mode .ce-toggle:hover .ce-level-vial { border-color: var(--gold); }
.ce-toggle:active .ce-level { transform: scale(0.95); }

.ce-toggle:focus-visible { outline: none; }
.ce-toggle:focus-visible .ce-level-vial {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold-dim);
}

/* Reduced motion: the bubble still moves so the state is
   readable, it just goes straight there without the slosh. */
@media (prefers-reduced-motion: reduce) {
  .ce-level-vial,
  .ce-level-bubble { transition-duration: 0.01s; }
}

/* Small caption beside the instrument, echoing the mode in words */
.ce-toggle-caption {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  font-family: var(--f-mono);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
}
.ce-toggle-caption span { transition: color 0.35s ease, opacity 0.35s ease; }
.ce-toggle-caption-blueprint { color: var(--teal); opacity: 1; }
.ce-toggle-caption-built { color: var(--muted); opacity: 0.4; }
html.day-mode .ce-toggle-caption-blueprint { color: var(--muted); opacity: 0.4; }
html.day-mode .ce-toggle-caption-built { color: var(--gold); opacity: 1; }

/* ── Theme-switch page transition: PLOTTER PASS ────────
   A wide-format plotter head rakes across the viewport
   and re-plots the sheet: ahead of the bar is the old
   drawing, behind it the new one, already laid down.

   The trick is that the outgoing and incoming snapshots
   are clipped to two parallel raked edges offset by a
   fixed gap, so neither layer paints inside that gap —
   what shows through is the background of the transition
   group itself. That background is a full-viewport
   gradient, so the exposed band reads as a lit plotter
   bar, and because the gradient is fixed to the viewport
   while the band travels across it, the bar cools from
   teal (blueprint ink) to gold (as-built) on the way
   over. Both layers share one duration and one easing,
   which is what keeps the gap a constant width.

   Deliberately no transforms on either layer: a scale of
   even half a percent would shift each clipped edge by a
   different amount and make the bar's width visibly
   breathe. Depth comes from opacity instead.

   Direction follows the instrument — left to right into
   As-Built, right to left back to Blueprint. Native View
   Transitions API; browsers without it, or with reduced
   motion, get the instant switch, so nothing breaks. ── */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

/* The lit bar. Only ever visible through the gap between
   the two clipped layers, so this gradient is sampled a
   slice at a time as the gap sweeps across it. */
::view-transition-group(root) {
  background-image: linear-gradient(
    100deg,
    #4ab8c8 0%,
    #7fd4e0 18%,
    #cfe8c8 38%,
    #e8b44a 58%,
    #fff3d4 72%,
    #e8b44a 86%,
    #d89b2e 100%
  );
}

::view-transition-old(root) {
  z-index: 1;
  animation:
    ce-plot-old-ltr var(--ce-plot-dur, 0.92s) var(--ce-plot-ease, cubic-bezier(.62,.03,.33,1)) both,
    ce-plot-recede  var(--ce-plot-dur, 0.92s) var(--ce-plot-ease, cubic-bezier(.62,.03,.33,1)) both;
}
::view-transition-new(root) {
  z-index: 2;
  animation:
    ce-plot-new-ltr var(--ce-plot-dur, 0.92s) var(--ce-plot-ease, cubic-bezier(.62,.03,.33,1)) both,
    ce-plot-ink     var(--ce-plot-dur, 0.92s) var(--ce-plot-ease, cubic-bezier(.62,.03,.33,1)) both;
}
html[data-ce-dir="rtl"]::view-transition-old(root) {
  animation-name: ce-plot-old-rtl, ce-plot-recede;
}
html[data-ce-dir="rtl"]::view-transition-new(root) {
  animation-name: ce-plot-new-rtl, ce-plot-ink;
}

/* ── LEFT → RIGHT (into As-Built) ──
   Raked edge: the top of the bar runs 14% ahead of the
   bottom, the way a plotter head leads across a sheet.
   New is clipped to everything left of the leading edge;
   old to everything right of that edge plus a 3.5% gap. */
@keyframes ce-plot-new-ltr {
  from { clip-path: polygon(-20% 0%,   -3.5% 0%,  -17.5% 100%, -20% 100%); }
  to   { clip-path: polygon(-20% 0%,  114%   0%,  100%   100%, -20% 100%); }
}
@keyframes ce-plot-old-ltr {
  from { clip-path: polygon(0%     0%, 120% 0%, 120% 100%, -14%   100%); }
  to   { clip-path: polygon(117.5% 0%, 120% 0%, 120% 100%, 103.5% 100%); }
}

/* ── RIGHT → LEFT (back to Blueprint) ── mirrored */
@keyframes ce-plot-new-rtl {
  from { clip-path: polygon(103.5% 0%, 120% 0%, 120% 100%, 117.5% 100%); }
  to   { clip-path: polygon(-14%   0%, 120% 0%, 120% 100%, 0%      100%); }
}
@keyframes ce-plot-old-rtl {
  from { clip-path: polygon(-20% 0%, 100%   0%, 114%  100%, -20% 100%); }
  to   { clip-path: polygon(-20% 0%, -17.5% 0%, -3.5% 100%, -20% 100%); }
}

/* Outgoing sheet dims very slightly as it is pulled off */
@keyframes ce-plot-recede {
  from { opacity: 1; }
  to   { opacity: 0.88; }
}
/* Incoming sheet comes up to full density behind the bar,
   like ink settling a beat after the head has passed */
@keyframes ce-plot-ink {
  from { opacity: 0.94; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
  ::view-transition-group(root) { background-image: none; }
}

/* Hamburger toggle - hidden on desktop, shown at the nav-collapse breakpoint */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 36px;
  height: 36px;
  background: transparent;
  border: 1px solid var(--border);
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 0.2s;
}
.nav-toggle:hover { border-color: var(--teal); }
.nav-toggle span {
  display: block;
  width: 16px;
  height: 1.5px;
  background: var(--teal);
  transition: transform 0.25s ease, opacity 0.25s ease;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.nav-status {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--f-mono);
  font-size: 10px;
  color: var(--muted);
}

.cta-download {
  gap: 8px;
}

.status-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #4ade80;
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(74,222,128,0.4); }
  50% { opacity: 0.8; box-shadow: 0 0 0 5px rgba(74,222,128,0); }
}

/* ── HERO ────────────────────────────────────────── */
.hero {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding-top: 60px;
}

.hero-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 80px 64px 80px 80px;
  position: relative;
  z-index: 1;
}

.eyebrow {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 24px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.eyebrow::before {
  content: '';
  width: 32px;
  height: 1px;
  background: var(--teal);
}

.hero-name {
  font-family: var(--f-display);
  font-size: clamp(48px, 5.5vw, 78px);
  font-weight: 300;
  line-height: 1.0;
  color: var(--heading);
  margin-bottom: 24px;
  letter-spacing: -1px;
}
.hero-name strong {
  font-weight: 700;
  color: var(--gold);
}

.hero-title {
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 3px;
  text-transform: uppercase;
  margin-bottom: 36px;
}

.student-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--gold-dim);
  border: 1px solid rgba(232,180,74,0.3);
  padding: 6px 14px;
  border-radius: 2px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--gold);
  text-transform: uppercase;
  margin-bottom: 28px;
  width: fit-content;
}

.hero-desc {
  font-size: 16px;
  font-weight: 300;
  color: var(--muted);
  max-width: 460px;
  line-height: 1.8;
  margin-bottom: 44px;
}
.hero-desc em {
  color: var(--text);
  font-style: normal;
}

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 60px;
}

.cta-primary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--gold);
  color: var(--bg);
  font-family: var(--f-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  padding: 14px 28px;
  text-decoration: none;
  transition: all 0.25s ease;
}
.cta-primary:hover {
  background: var(--white);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(232,180,74,0.3);
}

.cta-secondary {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  color: var(--muted);
  font-family: var(--f-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 2px;
  text-transform: uppercase;
  padding: 14px 28px;
  text-decoration: none;
  transition: all 0.25s ease;
}
.cta-secondary:hover {
  border-color: var(--teal);
  color: var(--teal);
}

.hero-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 28px 36px;
  padding-top: 40px;
  border-top: 1px solid var(--border);
}

.stat-val {
  font-family: var(--f-mono);
  font-size: 26px;
  font-weight: 700;
  color: var(--heading);
  line-height: 1;
}
.stat-val span { color: var(--gold); }
.stat-label {
  font-size: 11px;
  color: var(--muted);
  margin-top: 5px;
  letter-spacing: 1px;
}

/* ── HERO BLUEPRINT PANEL ────────────────────────── */
.hero-visual {
  background: var(--surface);
  border-left: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 48px;
  position: relative;
  overflow: hidden;
}

/* grid dots */
.hero-visual::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(74,184,200,0.15) 1px, transparent 1px);
  background-size: 28px 28px;
}

/* corner accents */
.corner {
  position: absolute;
  width: 20px; height: 20px;
}
.corner.tl { top: 16px; left: 16px; border-top: 1px solid var(--teal); border-left: 1px solid var(--teal); }
.corner.tr { top: 16px; right: 16px; border-top: 1px solid var(--teal); border-right: 1px solid var(--teal); }
.corner.bl { bottom: 16px; left: 16px; border-bottom: 1px solid var(--teal); border-left: 1px solid var(--teal); }
.corner.br { bottom: 16px; right: 16px; border-bottom: 1px solid var(--teal); border-right: 1px solid var(--teal); }

.bp-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 480px;
}

.bp-label {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--teal);
  opacity: 0.6;
  margin-bottom: 10px;
}

svg.blueprint {
  width: 100%;
  height: auto;
  display: block;
  filter: drop-shadow(0 16px 48px rgba(74,184,200,0.12));
}

/* ── HERO DWG: "Blueprint → As-Built" ──────────────
   Night mode shows the raw drawing exactly as drafted
   (cyan CAD ink on midnight blue floor plan). Day mode
   crossfades to an illustrated isometric of the actual
   finished house — same drafting-ink language (teal
   linework, gold accents), just the built phase of the
   same project. Both SVGs are stacked in the same grid
   cell and swap via opacity + a soft scale settle. */
.hero-visual-stack {
  position: relative;
  width: 100%;
  aspect-ratio: 800 / 580;
}
.hero-visual-stack > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

#hero-fp-svg {
  transition: opacity 0.5s ease, filter 0.5s ease, transform 0.6s ease;
  filter: drop-shadow(0 16px 40px rgba(74,184,200,0.1));
}
html.day-mode #hero-fp-svg {
  opacity: 0 !important;
  transform: scale(0.97);
  pointer-events: none;
}

#hero-mass-svg {
  opacity: 0;
  transform: scale(1.03);
  transition: opacity 0.6s ease 0.1s, transform 0.7s ease 0.1s;
  filter: drop-shadow(0 16px 40px rgba(169,122,40,0.14));
  pointer-events: none;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
html.day-mode #hero-mass-svg {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}
#hero-mass-svg.grabbing { cursor: grabbing; }
#hero-mass-svg #mass-render polygon,
#hero-mass-svg #mass-render line {
  transition: fill 0.15s ease;
}

/* "Drag to rotate" hint - shown once in day mode, fades on first interaction */
.mass-hint {
  position: absolute;
  left: 50%;
  bottom: 6px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  font: 600 10px/1 var(--mono, monospace);
  letter-spacing: 0.08em;
  color: var(--teal);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease 0.9s;
}
html.day-mode .mass-hint { opacity: 0.65; }
.mass-hint.hint-hide { opacity: 0 !important; transition: opacity 0.4s ease; }
.mass-hint svg { flex-shrink: 0; }

/* Building gallery nav (prev/next + counter) - lives top-right of the
   massing view, only meaningful (and visible) once As-Built mode is on */
.mass-nav {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.5s ease 0.15s, transform 0.5s ease 0.15s;
}
html.day-mode .mass-nav {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.mass-nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(169,122,40,0.35);
  background: rgba(255,255,255,0.55);
  color: var(--gold);
  cursor: pointer;
  padding: 0;
  transition: border-color 0.2s ease, background 0.2s ease, transform 0.15s ease;
}
.mass-nav-btn:hover { border-color: var(--gold); background: rgba(255,255,255,0.85); }
.mass-nav-btn:active { transform: scale(0.9); }
.mass-nav-btn svg { flex-shrink: 0; }
.mass-nav-count {
  font: 600 9px/1 var(--mono, monospace);
  letter-spacing: 0.08em;
  color: var(--gold);
  min-width: 40px;
  text-align: center;
}

/* Piece-by-piece assembly animation for the massing model - each polygon/
   line fades and rises into place, staggered bottom-up via animation-delay
   set inline by script.js. Opacity + a uniform translateY only - no scale.
   Scale shrinks each element toward its own bounding-box centre, and thin
   full-height mullion lines shrinking independently (each on its own
   stagger) is what produced the "melting/tapering grid" look mid-animation.
   A plain vertical shift never changes an element's size, so pieces can
   never visually taper or misalign while settling into place. */
@keyframes massPieceIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
#mass-render .piece {
  animation: massPieceIn 0.5s cubic-bezier(0.16, 0.84, 0.44, 1) both;
}

/* Hero panel dot grid + corner glow follow the same phase */
html.day-mode .hero-visual::before {
  background-image: radial-gradient(circle, rgba(28,32,28,0.12) 1px, transparent 1px);
}

/* animated draw-on */
.dl { stroke-dasharray: 800; stroke-dashoffset: 800; animation: draw 1.6s cubic-bezier(.4,0,.2,1) forwards; }
.dl.d1 { animation-delay: 0.1s; }
.dl.d2 { animation-delay: 0.25s; }
.dl.d3 { animation-delay: 0.4s; }
.dl.d4 { animation-delay: 0.55s; }
.dl.d5 { animation-delay: 0.65s; }
.dl.d6 { animation-delay: 0.75s; }
.dl.d7 { animation-delay: 0.85s; }
.dl.d8 { animation-delay: 0.95s; }
.dl.d9 { animation-delay: 1.05s; }
.dl.d10 { animation-delay: 1.15s; }
.dl.d11 { animation-delay: 1.25s; }
.dl.d12 { animation-delay: 1.35s; }

@keyframes draw { to { stroke-dashoffset: 0; } }

.fi { opacity: 0; animation: fi 0.5s ease forwards; }
.fi.f1 { animation-delay: 1.5s; }
.fi.f2 { animation-delay: 1.7s; }
.fi.f3 { animation-delay: 1.9s; }
@keyframes fi { to { opacity: 1; } }

/* typing cursor */
.bp-cursor {
  display: inline-block;
  width: 7px; height: 13px;
  background: var(--teal);
  animation: blink 1s step-end infinite;
  vertical-align: middle;
  margin-left: 2px;
}
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: 0; } }

/* ── ABOUT / INTRO STRIP ─────────────────────────── */
.about-strip {
  background: var(--surface);
  padding: 64px 80px;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  display: grid;
  grid-template-columns: 280px 1fr 1fr;
  gap: 64px;
  align-items: start;
}

.about-label {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 16px;
}

.about-heading {
  font-family: var(--f-display);
  font-size: 38px;
  font-weight: 600;
  color: var(--heading);
  line-height: 1.15;
}

.about-p {
  font-size: 15px;
  font-weight: 300;
  color: var(--muted);
  line-height: 1.8;
}
.about-p + .about-p { margin-top: 16px; }
.about-p strong { color: var(--text); font-weight: 500; }

/* ── SECTION COMMON ──────────────────────────────── */
section { padding: 96px 80px; position: relative; }

.sec-head {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 64px;
}
.sec-tag {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--teal);
  white-space: nowrap;
}
.sec-title {
  font-family: var(--f-display);
  font-size: 36px;
  font-weight: 600;
  color: var(--heading);
  letter-spacing: -0.5px;
}
.sec-rule {
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── PROJECTS ────────────────────────────────────── */
.projects-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}

.project-card {
  background: var(--surface);
  padding: 40px;
  cursor: default;
  transition: background 0.3s;
  position: relative;
  overflow: hidden;
}

.project-card:hover { background: var(--surface2); }

.project-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 3px; height: 0;
  background: var(--gold);
  transition: height 0.4s ease;
}
.project-card:hover::before { height: 100%; }

.project-type {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 3px;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 14px;
}

.mini-plan {
  width: 100%;
  height: auto;
  max-height: 320px;
  margin-bottom: 20px;
  background: #f4f2ee;
  border: 1px solid rgba(74,184,200,0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.mini-plan-img { transition: box-shadow 0.3s; width: 100%; height: 100%; }
.project-card:hover .mini-plan-img { box-shadow: 0 0 0 1px rgba(74,184,200,0.35) inset; }
.mini-plan-img img {
  width: 100%;
  height: 100%;
  max-height: 320px;
  object-fit: contain;
  object-position: center;
  display: block;
  transition: transform 0.5s ease;
}
.project-card:hover .mini-plan-img img { transform: scale(1.03); }

.plan-img-wrap {
  width: 100%;
  background: #060c14;
  padding: 0;
  display: block;
  border: 1px solid rgba(74,184,200,0.15);
  line-height: 0;
}
.plan-img-wrap img {
  width: 100%;
  height: auto;
  display: block;
}

.project-name {
  font-family: var(--f-display);
  font-size: 22px;
  font-weight: 600;
  color: var(--heading);
  margin-bottom: 10px;
  line-height: 1.25;
}

.project-desc {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.75;
  margin-bottom: 20px;
}

.project-specs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 20px;
}

.spec-pill {
  font-family: var(--f-mono);
  font-size: 9px;
  padding: 4px 10px;
  border: 1px solid var(--border);
  color: var(--muted);
  letter-spacing: 1px;
  background: transparent;
  transition: border-color 0.2s, color 0.2s;
}
.project-card:hover .spec-pill {
  border-color: rgba(74,184,200,0.25);
  color: var(--teal);
}

.project-status {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2px;
  text-transform: uppercase;
}
.status-academic { color: var(--teal); }
.status-thesis   { color: var(--gold); }
.status-collab   { color: #a78bfa; }
html.day-mode .status-collab { color: #7c3aed; }

/* ── EDUCATION / EXPERIENCE ──────────────────────── */
.edu-section { background: var(--surface); }

.cert-section {
  background: var(--bg);
  padding-top: 64px;
  padding-bottom: 80px;
}
.cert-sec-head { padding: 0 0 40px; }

.timeline {
  position: relative;
  padding-left: 36px;
  max-width: 760px;
}
.timeline::before {
  content: '';
  position: absolute;
  left: 0; top: 10px; bottom: 0;
  width: 1px;
  background: linear-gradient(to bottom, var(--teal), rgba(74,184,200,0));
}

.timeline-item {
  position: relative;
  margin-bottom: 52px;
  opacity: 0;
  transform: translateX(-16px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.timeline-item.visible { opacity: 1; transform: none; }

.timeline-item::before {
  content: '';
  position: absolute;
  left: -40px; top: 10px;
  width: 8px; height: 8px;
  border: 1.5px solid var(--teal);
  background: var(--bg);
  border-radius: 50%;
}

.tl-period {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--teal);
  text-transform: uppercase;
  margin-bottom: 8px;
}

.tl-role {
  font-family: var(--f-display);
  font-size: 20px;
  font-weight: 600;
  color: var(--heading);
  margin-bottom: 4px;
}

.tl-company {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 14px;
  letter-spacing: 0.3px;
}

.tl-desc {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.75;
}

/* ── SKILLS ──────────────────────────────────────── */
.skills-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}
.skills-grid-2col { grid-template-columns: 1fr 1fr; }

.skill-group {
  background: var(--surface);
  padding: 36px;
}

.sg-title {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 24px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.skill-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  font-size: 13px;
  color: var(--muted);
  transition: color 0.2s;
}
.skill-item:hover { color: var(--text); }

.skill-bar-track {
  width: 56px;
  height: 2px;
  background: rgba(255,255,255,0.06);
  position: relative;
  overflow: hidden;
}

.skill-bar-fill {
  position: absolute;
  top: 0; left: 0; height: 100%;
  background: linear-gradient(to right, var(--teal), var(--gold));
  width: 0;
  transition: width 1.2s cubic-bezier(.4,0,.2,1);
}
.skill-bar-fill.animated { width: var(--w); }

/* ── COURSEWORK / ACADEMICS ──────────────────────── */
.course-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  margin-top: 0;
}

.course-card {
  background: var(--surface);
  padding: 28px 32px;
  border-left: 3px solid transparent;
  transition: border-color 0.3s, background 0.3s;
}
.course-card:hover {
  background: var(--surface2);
  border-left-color: var(--gold);
}

.course-code {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--teal);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.course-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 4px;
  line-height: 1.35;
}
.course-grade {
  font-family: var(--f-mono);
  font-size: 10px;
  color: var(--gold);
}

/* ── CONTACT ─────────────────────────────────────── */
.contact-section { background: var(--surface); }

.contact-wrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: start;
}

.contact-left p {
  font-size: 15px;
  font-weight: 300;
  color: var(--muted);
  line-height: 1.8;
  margin-bottom: 36px;
}

.contact-line {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}

.cl-icon {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--muted);
  width: 56px;
  text-transform: uppercase;
}
.cl-val { color: var(--text); font-weight: 500; }
.cl-val a { color: var(--teal); text-decoration: none; }
.cl-val a:hover { text-decoration: underline; }

.contact-form {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.form-group { display: flex; flex-direction: column; gap: 7px; }
.hp-field {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-label {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--muted);
}

.form-input, .form-textarea {
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 13px 16px;
  font-family: var(--f-body);
  font-size: 14px;
  color: var(--text);
  outline: none;
  transition: border-color 0.2s;
  border-radius: 0;
}
.form-input:focus, .form-textarea:focus { border-color: var(--teal); }
.form-textarea { height: 120px; resize: vertical; }

.form-input.field-error, .form-textarea.field-error { border-color: #e0665a; }

.submit-btn {
  align-self: flex-start;
  background: var(--gold);
  color: var(--bg);
  font-family: var(--f-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  padding: 14px 32px;
  border: none;
  cursor: pointer;
  transition: all 0.25s ease;
}
.submit-btn:hover {
  background: var(--white);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(232,180,74,0.25);
}
.submit-btn:disabled {
  opacity: 0.6;
  cursor: default;
  transform: none;
  box-shadow: none;
}

/* Rubber-stamp shown when the message sends successfully.
   Styled like an engineering drawing-review stamp: teal
   double border (the "reviewed" ring) with the approval
   text in gold (matching the As-Built accent elsewhere). */
.stamp-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 20;
  opacity: 0;
}
.stamp-overlay.show {
  animation: stamp-in 0.55s cubic-bezier(0.2, 0.9, 0.3, 1.15) forwards;
}
.stamp-overlay.hide {
  animation: stamp-out 0.4s ease forwards;
}
.stamp-svg {
  width: min(78%, 300px);
  filter: drop-shadow(0 6px 18px rgba(0,0,0,0.35));
}
@keyframes stamp-in {
  0%   { opacity: 0; transform: scale(2.6) rotate(-9deg); }
  55%  { opacity: 1; transform: scale(0.92) rotate(-9deg); }
  75%  { transform: scale(1.04) rotate(-9deg); }
  100% { opacity: 1; transform: scale(1) rotate(-9deg); }
}
@keyframes stamp-out {
  from { opacity: 1; transform: scale(1) rotate(-9deg); }
  to   { opacity: 0; transform: scale(0.95) rotate(-9deg); }
}
/* A quick jolt on the whole form at the moment of impact */
.contact-form.stamp-hit { animation: stamp-shake 0.4s ease; }
@keyframes stamp-shake {
  0%, 100% { transform: translate(0, 0); }
  20%      { transform: translate(-3px, 1px); }
  40%      { transform: translate(3px, -1px); }
  60%      { transform: translate(-2px, 1px); }
  80%      { transform: translate(2px, 0); }
}

/* Custom cursor replaced by a JS-driven live reticle — see below. */

/* ── LIVE CAD CURSOR ─────────────────────────────────
   A slim crosshair + dot that follows the pointer, with
   a running coordinate readout like a CAD viewport. A
   thin gold ring pops in only over clickable elements
   (a "snap point" cue), and a caret bar shows over text
   fields. JS adds .ce-cursor-active to <html> once real
   mouse movement is detected — if JS never runs (or the
   device has no fine pointer), the native cursor is left
   alone. */
html.ce-cursor-active,
html.ce-cursor-active * {
  cursor: none !important;
}

.ce-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 99999;
  opacity: 0;
  transition: opacity 0.2s ease;
}
html.ce-cursor-active .ce-cursor { opacity: 1; }

.ce-cursor-ring {
  position: absolute;
  top: -20px;
  left: -20px;
  width: 40px;
  height: 40px;
  display: block;
  overflow: visible;
}
.ce-cursor-dot { transition: r 0.2s ease, fill 0.2s ease; }
.ce-cursor-textbar { opacity: 0; transition: opacity 0.15s ease; }
.ce-cursor-circle-group { transition: opacity 0.15s ease; }

/* The snap-point ring: invisible at rest, pops in on hover */
.ce-cursor-snap-ring {
  opacity: 0;
  transform: scale(0.5);
  transform-origin: 20px 20px;
  transition: opacity 0.15s ease, transform 0.15s cubic-bezier(.34,1.56,.64,1);
}

.ce-cursor-coords {
  position: absolute;
  top: 12px;
  left: 14px;
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 0.5px;
  color: var(--teal);
  text-shadow: 0 0 4px var(--bg), 0 0 4px var(--bg), 0 1px 2px var(--bg);
  white-space: nowrap;
  transition: opacity 0.15s ease;
}

/* Hovering a clickable element: ring pops in, dot turns gold */
.ce-cursor.is-active .ce-cursor-snap-ring { opacity: 0.8; transform: scale(1); }
.ce-cursor.is-active .ce-cursor-dot { r: 1.8; fill: var(--gold); }
.ce-cursor.is-active .ce-cursor-coords { opacity: 0; }
.ce-cursor.is-active .ce-cursor-label { opacity: 1; }

.ce-cursor-label {
  position: absolute;
  top: 12px;
  left: 14px;
  font-family: var(--f-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 1.5px;
  color: var(--gold);
  text-shadow: 0 0 4px var(--bg), 0 0 4px var(--bg), 0 1px 2px var(--bg);
  opacity: 0;
  white-space: nowrap;
  transition: opacity 0.15s ease;
}

/* Hovering a text field: crosshair hides, a thin caret bar shows instead */
.ce-cursor.is-text .ce-cursor-circle-group { opacity: 0; }
.ce-cursor.is-text .ce-cursor-textbar { opacity: 1; }
.ce-cursor.is-text .ce-cursor-coords,
.ce-cursor.is-text .ce-cursor-label { opacity: 0; }

/* Quick pulse on click, for tactile feedback */
.ce-cursor.is-click .ce-cursor-ring { transform: scale(0.82); transition: transform 0.12s ease; }

@media (pointer: coarse) {
  .ce-cursor { display: none; }
}

/* Some mobile preview/testing environments still report a fine
   pointer at narrow widths, which let the desktop-only CAD cursor
   slip through and sit at a stale position over the collapsed nav's
   toggle + hamburger button. This is a hard backstop: below the nav
   collapse breakpoint, the cursor overlay never renders, regardless
   of what pointer type the browser reports. */
@media (max-width: 768px) {
  .ce-cursor { display: none !important; }
}

.form-status {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.5px;
  min-height: 14px;
  transition: color 0.2s;
}
.form-status.status-error { color: #e0665a; }
.form-status.status-ok { color: var(--teal); }
html.day-mode .form-status.status-error { color: #c0392b; }

/* ── FOOTER ──────────────────────────────────────── */
footer {
  background: var(--bg);
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 1px;
  padding: 28px 80px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
footer .gold { color: var(--gold); }
.footer-credits { font-size: 9px; opacity: 0.75; }
.footer-credits a { color: var(--teal); text-decoration: none; }
.footer-credits a:hover { text-decoration: underline; }

/* ── DESIGN PROCESS SECTION ──────────────────────── */
.process-section { background: var(--bg); }

.process-steps {
  position: relative;
  display: flex;
  flex-direction: column;
}

/* The connecting rail, run behind every step's number column.
   Colored teal → gold to echo the Blueprint → As-Built idea
   used elsewhere on the site (e.g. the theme toggle). */
.process-steps::before {
  content: '';
  position: absolute;
  top: 40px;
  bottom: 40px;
  left: 72px;
  width: 2px;
  background: linear-gradient(to bottom, var(--teal), var(--gold));
  opacity: 0.35;
  z-index: 0;
}

.process-step {
  position: relative;
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: 28px;
  align-items: start;
  padding: 28px 0;
  border-top: 1px solid var(--border);
  z-index: 1;
}
.process-step:first-child { border-top: none; padding-top: 8px; }
.process-step:last-child { padding-bottom: 8px; }

.process-num {
  position: relative;
  font-family: var(--f-mono);
  font-size: 28px;
  font-weight: 600;
  color: var(--gold);
  opacity: 0.55;
  letter-spacing: 1px;
  line-height: 1;
  transition: opacity 0.25s ease;
}
/* The node marking this step on the rail */
.process-num::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--gold);
  z-index: 2;
  transition: border-color 0.25s ease, background 0.25s ease;
}
.process-step:hover .process-num { opacity: 1; }
.process-step:hover .process-num::after { border-color: var(--teal); }

.process-title {
  font-family: var(--f-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--heading);
  margin-bottom: 8px;
  transition: color 0.25s ease;
}
.process-step:hover .process-title { color: var(--gold); }

.process-desc {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.75;
  max-width: 640px;
}

@media (max-width: 640px) {
  .process-steps::before { left: 46px; }
  .process-step { grid-template-columns: 54px 1fr; gap: 16px; padding: 20px 0; }
  .process-num { font-size: 18px; }
}

/* ── PROJECT CARD CLICKABLE ──────────────────────── */
.project-card { cursor: pointer; }
.project-card:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: -1px;
}

/* ── PDF VIEWER MODAL ────────────────────────────── */
.pdf-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 999;
  align-items: center;
  justify-content: center;
}
.pdf-modal.open { display: flex; }

.pdf-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6,10,16,0.86);
  backdrop-filter: blur(3px);
}

.pdf-modal-panel {
  position: relative;
  width: min(920px, 94vw);
  height: min(88vh, 980px);
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

.pdf-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.pdf-modal-title {
  font-family: var(--f-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--heading);
  padding-right: 16px;
}
.pdf-modal-close {
  font-family: var(--f-mono);
  font-size: 14px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  width: 32px; height: 32px;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.2s, border-color 0.2s;
}
.pdf-modal-close:hover { color: var(--gold); border-color: var(--gold); }

.pdf-modal-body {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px;
  overflow: hidden;
  min-height: 0;
}

.pdf-canvas-wrap {
  flex: 1;
  height: 100%;
  min-width: 0;
  min-height: 0;
  display: flex;
  overflow: auto;
  background: #0a1018;
  position: relative;
  cursor: grab;
  touch-action: pan-x pan-y;
}
#pdf-canvas { display: block; margin: auto; flex-shrink: 0; box-shadow: 0 0 0 1px rgba(74,184,200,0.15); }

.pdf-loading {
  position: absolute;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--muted);
}

.pdf-nav-btn {
  font-family: var(--f-display);
  font-size: 22px;
  color: var(--text);
  background: var(--surface2);
  border: 1px solid var(--border);
  width: 40px; height: 56px;
  flex-shrink: 0;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.pdf-nav-btn:hover:not(:disabled) { color: var(--gold); border-color: var(--gold); }
.pdf-nav-btn:disabled { opacity: 0.3; cursor: default; }

.pdf-modal-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
#pdf-page-indicator {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 1px;
  color: var(--muted);
}
.pdf-zoom-controls {
  display: flex;
  align-items: center;
  gap: 6px;
}
.pdf-zoom-btn {
  font-family: var(--f-mono);
  font-size: 14px;
  color: var(--text);
  background: var(--surface2);
  border: 1px solid var(--border);
  width: 26px; height: 26px;
  line-height: 1;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}
.pdf-zoom-btn:hover { color: var(--gold); border-color: var(--gold); }
.pdf-zoom-reset {
  width: auto;
  padding: 0 8px;
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
}
#pdf-zoom-level {
  font-family: var(--f-mono);
  font-size: 10px;
  color: var(--muted);
  min-width: 38px;
  text-align: center;
}
.pdf-download-link {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--teal);
  text-decoration: none;
  border: 1px solid rgba(74,184,200,0.3);
  padding: 8px 14px;
  transition: border-color 0.2s, color 0.2s;
}
.pdf-download-link:hover { color: var(--gold); border-color: var(--gold); }

@media (max-width: 640px) {
  .pdf-modal-panel {
    width: 100vw;
    height: 100vh;
    height: 100dvh; /* avoids mobile browser chrome clipping the panel */
  }
  .pdf-modal-header { padding: 12px 14px; }
  .pdf-modal-title {
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .pdf-nav-btn { width: 36px; height: 52px; font-size: 18px; }
  .pdf-modal-body { padding: 8px; gap: 6px; }

  .pdf-modal-footer {
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px 14px;
    padding: 10px 12px;
  }
  #pdf-page-indicator {
    order: -1;
    flex: 1 0 100%;
    text-align: center;
  }
  .pdf-download-link { padding: 8px 12px; font-size: 9px; }
}

/* ── SCROLL REVEAL ───────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.visible { opacity: 1; transform: none; }

/* ── RESPONSIVE ──────────────────────────────────── */
@media (max-width: 960px) {
  .hero { grid-template-columns: 1fr; }
  .hero-visual { display: none; }
  .hero-text { padding: 60px 32px 80px; }
  nav { padding: 0 24px; }
  .nav-status { display: none; }
  section { padding: 64px 32px; }
  .about-strip { grid-template-columns: 1fr; gap: 32px; padding: 48px 32px; }
  .projects-grid {
    grid-template-columns: 1fr;
    gap: 16px;
    background: transparent;
    border: none;
  }
  .project-card { border: 1px solid var(--border); }
  .mini-plan { height: 220px; max-height: none; }
  .skills-grid { grid-template-columns: 1fr; }
  .course-grid { grid-template-columns: 1fr 1fr; }
  .contact-wrap { grid-template-columns: 1fr; gap: 48px; }
  footer { padding: 24px 32px; flex-direction: column; gap: 8px; text-align: center; }
  .plan-meta { grid-template-columns: repeat(2,1fr); }
}

/* ── NAV COLLAPSE (hamburger) ────────────────────── */
@media (max-width: 768px) {
  .nav-toggle { display: flex; }

  .nav-links {
    position: fixed;
    top: 60px;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    max-height: 0;
    overflow: hidden;
    background: rgba(14,17,23,0.98);
    backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--border);
    transition: max-height 0.3s ease;
    z-index: 99;
  }
  .nav-links.open { max-height: 320px; }

  .nav-links li { width: 100%; }
  .nav-links a {
    display: block;
    padding: 16px 24px;
    border-bottom: 1px solid var(--border);
    font-size: 12px;
  }
  .nav-links a::after { display: none; }
}

/* ── SMALL PHONES ─────────────────────────────────── */
@media (max-width: 480px) {
  nav { padding: 0 16px; height: 56px; }
  .nav-logo { font-size: 10px; }
  #intro-name { bottom: 24px; letter-spacing: 2px; }

  .ce-toggle-caption { display: none; }

  .hero-text { padding: 44px 20px 56px; }
  .hero-name { letter-spacing: -0.5px; }
  .hero-desc { font-size: 14.5px; margin-bottom: 32px; }
  .hero-ctas { gap: 12px; margin-bottom: 44px; }
  .cta-primary, .cta-secondary { padding: 12px 20px; font-size: 11px; }
  .hero-stats { gap: 20px 28px; padding-top: 28px; }
  .stat-val { font-size: 22px; }

  section { padding: 48px 20px; }
  .cert-section { padding-top: 40px; padding-bottom: 48px; }
  .sec-head { gap: 12px; margin-bottom: 40px; flex-wrap: wrap; }
  .sec-title { font-size: 26px; }

  .about-strip { padding: 40px 20px; gap: 28px; }
  .about-heading { font-size: 28px; }

  .project-card { padding: 24px 20px; }
  .mini-plan { height: 190px; }
  .project-name { font-size: 19px; }

  .course-grid { grid-template-columns: 1fr; }
  .course-card { padding: 22px 20px; }

  .skill-group { padding: 24px 20px; }
  .skill-item {
    flex-wrap: wrap;
    gap: 6px 12px;
    align-items: flex-start;
  }

  .timeline { padding-left: 28px; }
  .timeline-item::before { left: -32px; }
  .tl-role { font-size: 17px; }

  .contact-line { flex-wrap: wrap; gap: 4px 18px; padding: 14px 0; }
  .cl-icon { width: auto; }

  .form-textarea { height: 100px; }

  footer { padding: 20px 20px; font-size: 9px; }
}

@media (prefers-reduced-motion: reduce) {
  .dl, .fi, .reveal, .timeline-item { animation: none; transition: none; opacity: 1; transform: none; }
}

/* ── BEAM LAB ─────────────────────────────────────
   A live elastic beam solver presented as a drafting
   sheet: title block, elevation, SFD, BMD, and a
   results panel. All SVG colour comes from the shared
   tokens, so it follows Blueprint ⇄ As-Built for free. */
.beamlab-section { background: var(--surface); }

.bl-intro {
  max-width: 640px;
  margin: -40px 0 40px;
  font-size: 15px;
  line-height: 1.75;
  color: var(--muted);
}

.bl-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 290px;
  gap: 28px;
  align-items: start;
}

.bl-sheet {
  position: relative;
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: 2px;
  overflow: hidden;
}
.bl-titlebar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--gold);
}
.bl-titlebar-right { color: var(--muted); text-align: right; }
.bl-scroll { overflow-x: auto; }
#bl-svg { display: block; width: 100%; height: auto; }

.bl-hint {
  position: absolute;
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  font: 600 9px/1 var(--f-mono);
  letter-spacing: 0.1em;
  color: var(--teal);
  opacity: 0.7;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.bl-hint.is-hidden { opacity: 0; }

/* ── drawing elements ── */
#bl-svg text { font-family: var(--f-mono); fill: var(--muted); }
.bl-lab { font-size: 10px; letter-spacing: 0.6px; }
.bl-val { font-size: 11px; fill: var(--text); }
.bl-tick { stroke: var(--border); stroke-width: 1; }
.bl-axis { stroke: var(--muted); stroke-width: 1; opacity: 0.55; }
.bl-beam { stroke: var(--heading); stroke-width: 3.5; stroke-linecap: square; }
.bl-sup  { stroke: var(--text); stroke-width: 1.6; fill: var(--surface2); }
.bl-grnd { stroke: var(--muted); stroke-width: 1; opacity: 0.7; }
.bl-defl { stroke: var(--gold); stroke-width: 2; stroke-dasharray: 6 4; fill: none; }
.bl-load { stroke: var(--gold); stroke-width: 2; fill: var(--gold); }
.bl-udl  { stroke: var(--teal); stroke-width: 1.3; fill: var(--teal); opacity: 0.8; }
.bl-rxn  { stroke: var(--teal); stroke-width: 1.8; fill: var(--teal); }
.bl-shear  { fill: var(--teal-dim); stroke: var(--teal); stroke-width: 1.6; }
.bl-moment { fill: var(--gold-dim); stroke: var(--gold); stroke-width: 1.6; }
.bl-handle {
  fill: var(--gold);
  stroke: var(--bg);
  stroke-width: 2.5;
  cursor: grab;
  touch-action: none;
}
.bl-handle:active { cursor: grabbing; }
.bl-handle:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }
.bl-handle-hit { fill: transparent; cursor: grab; touch-action: none; }

/* ── control panel ── */
.bl-panel {
  border: 1px solid var(--border);
  background: var(--bg);
  border-radius: 2px;
  padding: 18px 18px 20px;
}
.bl-panel-head {
  font-family: var(--f-mono);
  font-size: 9px;
  letter-spacing: 2.4px;
  text-transform: uppercase;
  color: var(--teal);
  margin: 20px 0 10px;
}
.bl-panel-head:first-child { margin-top: 0; }

.bl-seg { display: grid; gap: 5px; }
.bl-seg-btn {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.8px;
  text-align: left;
  padding: 8px 10px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 2px;
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.bl-seg-btn:hover { color: var(--text); border-color: var(--gold); }
.bl-seg-btn.is-on {
  color: var(--gold);
  border-color: var(--gold);
  background: var(--gold-dim);
}

.bl-ctl { display: block; margin-bottom: 14px; }
.bl-ctl-lab {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.6px;
  color: var(--muted);
  margin-bottom: 6px;
}
.bl-ctl-lab b { color: var(--text); font-weight: 400; }
.bl-ctl input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 2px;
  background: var(--border);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
.bl-ctl input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--gold);
  border: 2px solid var(--bg);
  cursor: pointer;
}
.bl-ctl input[type="range"]::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border: 2px solid var(--bg);
  border-radius: 50%;
  background: var(--gold);
  cursor: pointer;
}
.bl-ctl input[type="range"]:focus-visible { outline: 2px solid var(--teal); outline-offset: 4px; }

.bl-out { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); }
.bl-out > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 7px 10px;
  background: var(--bg);
}
.bl-out dt { font-family: var(--f-mono); font-size: 10px; color: var(--muted); }
.bl-out dd { font-family: var(--f-mono); font-size: 11px; color: var(--text); text-align: right; }

.bl-check {
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 2px;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.8px;
  text-align: center;
  color: var(--muted);
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.bl-check.is-pass { color: var(--teal); border-color: var(--teal); background: var(--teal-dim); }
.bl-check.is-fail { color: var(--gold); border-color: var(--gold); background: var(--gold-dim); }

.bl-note {
  margin-top: 14px;
  font-size: 11px;
  line-height: 1.6;
  color: var(--muted);
  opacity: 0.85;
}

@media (max-width: 980px) {
  .bl-wrap { grid-template-columns: minmax(0, 1fr); }
  .bl-intro { margin-top: -24px; }
  #bl-svg { min-width: 640px; }
}
@media (prefers-reduced-motion: reduce) {
  .bl-hint { transition: none; }
}