/* ═══════════════════════════════════════
   CASE STUDY TEMPLATE
   Inherits tokens + base styles from global.css
   Only declares overrides and case-specific components
═══════════════════════════════════════ */

/* Case study design tokens — shared by all case pages.
   Individual cases may override these in their own :root or
   inside media queries for mobile-specific adjustments. */
:root {
  /* Aliases for legacy selectors */
  --dark:            var(--ink-soft);
  --near-black:      var(--ink);

  /* Spacing scale */
  --cs-gutter:       48px;      /* horizontal page margin */
  --cs-section-gap:  3rem;      /* vertical gap between sections */
  --cs-inner-gap:    2rem;      /* gap within a section */
  --cs-element-gap:  1.25rem;   /* gap between elements */
  --cs-content-max:  1400px;    /* max content width */
}

/* Body overrides (global.css sets font-weight: 300; case studies use 400 for longer reading) */
body {
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.6;
}

/* Code cascade canvas background */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-image: url('data:image/svg+xml;utf8,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><text x="10" y="20" font-family="Space Mono" font-size="10" fill="%23080808" opacity="0.06">{}</text><text x="10" y="40" font-family="Space Mono" font-size="9" fill="%23080808" opacity="0.04">const</text><text x="10" y="60" font-family="Space Mono" font-size="10" fill="%23080808" opacity="0.05">let x</text><text x="10" y="80" font-family="Space Mono" font-size="9" fill="%23080808" opacity="0.06">=</text></svg>');
  background-repeat: repeat;
  pointer-events: none;
  z-index: 0;
}

/* Main wrapper */
.case-study {
  position: relative;
  z-index: 1;
}

/* Navigation */
nav {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid var(--ink);
  backdrop-filter: blur(10px);
  background-color: color-mix(in srgb, var(--bg) 95%, transparent);
}

.nav-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.5rem 2rem;
  max-width: 1400px;
  margin: 0 auto;
}

.nav-logo {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: 1px;
  text-decoration: none;
  color: var(--ink);
  transition: color 0.3s var(--ease);
}

.nav-logo em {
  color: var(--accent);
  font-style: normal;
  margin: 0 2px;
}

.nav-logo:hover {
  color: var(--accent);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 2.5rem;
  list-style: none;
}

.nav-links a {
  font-family: var(--f-mono);
  font-size: 0.875rem;
  text-decoration: none;
  color: var(--ink);
  transition: color 0.3s var(--ease);
  position: relative;
}

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

.nav-links a:hover::after {
  width: 100%;
}

.status-dot {
  width: 8px;
  height: 8px;
  background: var(--accent);
  border-radius: 50%;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* Back to projects link */
.back-link {
  max-width: 1400px;
  margin: 0 auto;
  padding: 1rem 2rem;
  font-family: var(--f-mono);
  font-size: 0.875rem;
}

.back-link a {
  color: var(--accent);
  text-decoration: none;
  transition: color 0.3s var(--ease);
}

.back-link a:hover {
  color: var(--ink);
}

/* Hero section */
.hero {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  padding: 4rem 2rem;
  max-width: 1400px;
  margin: 0 auto;
  position: relative;
  overflow: hidden;
}

.hero::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 500px;
  height: 500px;
  background: radial-gradient(circle, rgba(100, 200, 255, 0.08) 0%, transparent 70%);
  pointer-events: none;
}

.hero-number {
  font-family: var(--f-mono);
  font-size: 0.875rem;
  color: var(--accent-on-light);
  margin-bottom: 2rem;
  opacity: 0;
  animation: slideUp 0.8s var(--ease) 0.1s forwards;
}

.hero-title {
  font-family: var(--f-display);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  font-weight: 700;
  line-height: 1.1;
  margin-bottom: 2rem;
  letter-spacing: -1px;
  color: var(--ink);
  opacity: 0;
  animation: slideUp 0.8s var(--ease) 0.2s forwards;
  max-width: 900px;
}

.hero-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 3rem;
  opacity: 0;
  animation: slideUp 0.8s var(--ease) 0.3s forwards;
}

.tag {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  padding: 0.5rem 1rem;
  border: 1px solid var(--ink);
  border-radius: 2px;
  text-transform: uppercase;
  letter-spacing: 1px;
  transition: all 0.3s var(--ease);
}

.tag:hover {
  background: var(--ink);
  color: var(--bg);
}

.hero-description {
  font-family: var(--f-body);
  font-size: 1.125rem;
  line-height: 1.8;
  margin-bottom: 3rem;
  max-width: 600px;
  opacity: 0;
  animation: slideUp 0.8s var(--ease) 0.4s forwards;
}

.hero-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 2rem;
  opacity: 0;
  animation: slideUp 0.8s var(--ease) 0.5s forwards;
  max-width: 800px;
}

.meta-item {
  font-family: var(--f-mono);
  font-size: 0.875rem;
}

.meta-label {
  color: var(--accent-on-light);
  text-transform: uppercase;
  letter-spacing: 1px;
  font-size: 0.75rem;
  margin-bottom: 0.5rem;
  display: block;
}

.meta-value {
  color: var(--ink);
  font-size: 1rem;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Section structure */
section {
  max-width: 1400px;
  margin: 0 auto;
  padding: 6rem 2rem;
  position: relative;
}

.section-label {
  position: absolute;
  left: 2rem;
  top: 6rem;
  font-family: var(--f-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 2px;
  color: var(--accent-on-light);
  writing-mode: vertical-rl;
  text-orientation: mixed;
  opacity: 0;
  animation: fadeIn 0.8s var(--ease) 0.3s forwards;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ═══ OVERVIEW CARDS — dark DS/Matrix component ═══ */
.overview {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--cs-inner-gap, 2rem);
  padding-left: 3rem;
  counter-reset: ov-card;
}

.overview-item {
  background: var(--ink-soft, #141414);
  border: 1px solid rgba(240, 237, 232, 0.06);
  padding: var(--cs-inner-gap, 2rem);
  position: relative;
  overflow: hidden;
  opacity: 0;
  transition: opacity 0.6s var(--ease, ease), border-color 0.3s;
  counter-increment: ov-card;
}

/* scan-line overlay */
.overview-item::before {
  content: '';
  position: absolute; inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 2px,
    rgba(240, 237, 232, 0.015) 2px,
    rgba(240, 237, 232, 0.015) 4px
  );
  pointer-events: none; z-index: 1;
}

/* corner bracket — top-left */
.overview-item::after {
  content: '';
  position: absolute; top: 10px; left: 10px;
  width: 16px; height: 16px;
  border-top: 1px solid var(--accent, #00E87A);
  border-left: 1px solid var(--accent, #00E87A);
  pointer-events: none; z-index: 2;
  opacity: 0.5;
  transition: opacity 0.3s;
}

.overview-item:hover::after { opacity: 1; }
.overview-item:hover { border-color: rgba(240, 237, 232, 0.12); }

.overview-item.in { opacity: 1; }

/* numbered counter label */
.overview-item h3::before {
  content: '// 0' counter(ov-card);
  display: block;
  font-family: var(--f-mono, 'Space Mono', monospace);
  font-size: 0.58rem;
  font-weight: 400;
  color: var(--accent, #00E87A);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: 0.6rem;
}

.overview-item h3 {
  font-family: var(--f-display, 'Rajdhani', sans-serif);
  font-size: 1.25rem;
  margin-bottom: 1rem;
  color: var(--bg, #F0EDE8);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  position: relative; z-index: 2;
}

.overview-item p {
  font-size: 0.95rem;
  line-height: 1.8;
  color: var(--ink-on-dark, rgba(240, 237, 232, 0.72));
  font-weight: 300;
  position: relative; z-index: 2;
}

/* Process section */
.process-container {
  padding-left: 8rem;
}

.process-step {
  display: grid;
  grid-template-columns: 250px 1fr;
  gap: 3rem;
  margin-bottom: 5rem;
  align-items: start;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}

.process-step.in {
  opacity: 1;
}

.process-number {
  font-family: var(--f-display);
  font-size: 3rem;
  font-weight: 700;
  color: var(--accent-on-light);
  line-height: 1;
}

.process-title {
  font-family: var(--f-display);
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 1rem;
  color: var(--ink);
}

.process-content p {
  font-size: 1rem;
  line-height: 1.8;
  margin-bottom: 2rem;
}

.image-placeholder {
  width: 100%;
  height: 350px;
  background: var(--ink-soft);
  border: 1px solid var(--ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  position: relative;
  margin-top: 2rem;
  /* Rule #4 — nunca grudar conteúdo nas bordas.
     Horizontal breath room protege também os corner brackets (::before/::after
     ficam a 15px da borda, texto começa a 1.5rem = 24px → sem colisão). */
  padding: 2rem 1.5rem;
  box-sizing: border-box;
}

.image-placeholder::before,
.image-placeholder::after {
  content: '';
  position: absolute;
  background: var(--accent);
}

.image-placeholder::before {
  width: 20px;
  height: 20px;
  border-top: 2px solid var(--accent);
  border-left: 2px solid var(--accent);
  background: none;
  top: 15px;
  left: 15px;
}

.image-placeholder::after {
  width: 20px;
  height: 20px;
  border-bottom: 2px solid var(--accent);
  border-right: 2px solid var(--accent);
  background: none;
  bottom: 15px;
  right: 15px;
}

.image-placeholder-text {
  font-family: var(--f-mono);
  font-size: 0.875rem;
  color: var(--accent);
  text-align: center;
  position: relative;
  z-index: 1;
  letter-spacing: 1px;
}

.image-placeholder-hint {
  font-family: var(--f-mono);
  font-size: 0.62rem;
  color: rgba(240, 237, 232, 0.45);
  text-align: center;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  position: relative;
  z-index: 1;
}

/* Classified modifier — used by case-02 Process step placeholders and
   any future NDA-gated deliverable. Tints border + text + corner brackets
   red and adds a subtle pulse. Background stays --ink-soft (shared), so
   the modifier is fully composable: add `is-classified` to any existing
   .image-placeholder to get the NDA treatment. */
.image-placeholder.is-classified {
  border-color: rgba(255, 51, 51, 0.2);
}
.image-placeholder.is-classified::before {
  border-top-color: var(--classified-red);
  border-left-color: var(--classified-red);
  opacity: 0.6;
  animation: classifiedPulse 4s infinite;
}
.image-placeholder.is-classified::after {
  border-bottom-color: var(--classified-red);
  border-right-color: var(--classified-red);
  opacity: 0.6;
  animation: classifiedPulse 4s infinite;
}
.image-placeholder.is-classified .image-placeholder-text {
  color: var(--classified-red);
}

/* Classified pulse — shared timer used by modifier corner brackets,
   case-02 restricted-badge / classified-badge / classified-card-status dot.
   Low-impact opacity-only keyframe so it composes safely with other anims. */
@keyframes classifiedPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.5; }
}
.image-placeholder.is-classified::before,
.image-placeholder.is-classified::after {
  /* Redeclare opacity baseline so the pulse keyframe has a clean 100% state */
  background: none;
}

@media (prefers-reduced-motion: reduce) {
  .image-placeholder.is-classified::before,
  .image-placeholder.is-classified::after { animation: none; }
}

/* Deliverables section */
.deliverables-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(350px, 100%), 1fr));
  gap: 2rem;
  padding-left: 8rem;
}

.deliverable-item {
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}

.deliverable-item.in {
  opacity: 1;
}

.deliverable-image {
  width: 100%;
  height: 300px;
  background: var(--ink-soft);
  border: 1px solid var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  margin-bottom: 1.5rem;
}

.deliverable-image::before,
.deliverable-image::after {
  content: '';
  position: absolute;
  background: var(--accent);
}

.deliverable-image::before {
  width: 16px;
  height: 16px;
  border-top: 2px solid var(--accent);
  border-left: 2px solid var(--accent);
  background: none;
  top: 12px;
  left: 12px;
}

.deliverable-image::after {
  width: 16px;
  height: 16px;
  border-bottom: 2px solid var(--accent);
  border-right: 2px solid var(--accent);
  background: none;
  bottom: 12px;
  right: 12px;
}

.deliverable-placeholder-text {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  color: var(--accent);
  text-align: center;
  letter-spacing: 1px;
}

.deliverable-caption {
  font-family: var(--f-mono);
  font-size: 0.875rem;
  color: var(--ink);
  text-align: center;
}

/* Results section */
.results-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 3rem;
  padding-left: 8rem;
}

.result-item {
  text-align: center;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}

.result-item.in {
  opacity: 1;
}

.result-number {
  font-family: var(--f-display);
  font-size: 3.5rem;
  font-weight: 700;
  color: var(--accent-on-light);
  line-height: 1;
  margin-bottom: 0.5rem;
}

.result-label {
  font-family: var(--f-mono);
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ink);
}

/* Next project nav */
.next-project {
  max-width: 1400px;
  margin: 0 auto;
  padding: 6rem 2rem;
  border-top: 1px solid var(--ink);
}

.next-project-label {
  font-family: var(--f-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--accent-on-light);
  margin-bottom: 1rem;
}

.next-project-link {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  text-decoration: none;
  color: var(--ink);
  transition: all 0.3s var(--ease);
  padding: 2rem;
  margin-left: -2rem;
  border-radius: 4px;
}

.next-project-link:hover {
  background: rgba(0, 232, 122, 0.05);
  padding-left: 3rem;
}

.next-project-arrow {
  font-family: var(--f-mono);
  font-size: 1.5rem;
  color: var(--accent-on-light);
  transition: transform 0.3s var(--ease);
}

.next-project-link:hover .next-project-arrow {
  transform: translateX(8px);
}

.next-project-info h3 {
  font-family: var(--f-display);
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.next-project-number {
  font-family: var(--f-mono);
  font-size: 0.875rem;
  color: var(--accent-on-light);
}

/* Tablet */
@media (max-width: 1024px) {
  .nav-container { padding: 1rem 2rem; }
  .nav-links { gap: 1.5rem; }
  .hero { padding: 2.5rem 2rem; }
  .hero::before { width: 400px; height: 400px; }
  section { padding: 4rem 2rem; }
  .overview, .deliverables-grid, .results-container { padding-left: 4rem; }
  .process-container { padding-left: 4rem; }
  .process-step { grid-template-columns: 160px 1fr; }
  .section-label { display: none; }
  .image-placeholder { height: 280px; }
  .deliverable-image { height: 240px; }
  .result-number { font-size: 2.5rem; }
}

/* Case-study hamburger: hide desktop nav links/status, show toggle at 860px.
   Kept inside case-study.css so case pages with sticky <nav> behave consistently. */
@media (max-width: 860px) {
  .nav-container { padding: 0.75rem 1.25rem; }
  .nav-links { display: none; }
  .nav-status { display: none; }
  .nav-toggle { display: inline-flex; }
}

/* Shrink shared design tokens on mobile so vertical rhythm stays tight.
   Previously adjacent .cs-sections double-padded (3rem + 3rem = ~96px of white). */
@media (max-width: 768px) {
  :root {
    --cs-section-gap: 1.75rem;
    --cs-inner-gap:   1.25rem;
    --cs-element-gap: 1rem;
  }
  .cs-section { padding: var(--cs-section-gap) var(--cs-gutter); }
}

/* Mobile */
@media (max-width: 768px) {
  .nav-container {
    padding: 0.75rem 1.25rem;
  }

  .hero {
    padding: 2rem 1.25rem;
    min-height: auto;
    padding-top: 2rem;
    overflow: visible;
  }

  .hero::before {
    width: 200px;
    height: 200px;
  }

  .hero-title {
    font-size: clamp(1.5rem, 7vw, 2rem);
  }

  .hero-description {
    max-width: 100%;
    font-size: 1rem;
  }

  .hero-meta {
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
  }

  .hero-tags {
    gap: 0.5rem;
  }

  .tag {
    font-size: 0.65rem;
    padding: 0.4rem 0.75rem;
    letter-spacing: 0.5px;
  }

  .section-label {
    left: 1.5rem;
    writing-mode: horizontal-tb;
    text-orientation: initial;
    position: relative;
    top: 0;
    margin-bottom: 1rem;
  }

  /* Reduced vertical rhythm for mobile — 4rem was too generous combined with
     inner content margins, creating big empty bands between sections. */
  section {
    padding: 2.75rem 1.25rem;
  }

  .overview, .deliverables-grid, .results-container {
    padding-left: 0;
  }

  .process-container {
    padding-left: 0;
  }

  .process-step {
    grid-template-columns: 1fr;
    gap: 1rem;
    margin-bottom: 2.5rem;
  }

  .image-placeholder { height: 180px; margin-top: 1.25rem; }
  .deliverable-image { height: 160px; }
  .result-number { font-size: 2rem; }

  /* Hero mockup labels that float -1.75rem below parent create awkward empty gaps
     on mobile where the section padding is already tight. Pin them flush. */
  .cs-mockup-label { position: static !important; margin-top: 0.75rem; display: block; }
}

/* DS Decode & Glitch — case studies use darker decoding char for contrast on dense text bodies.
   Base selectors (display, transition, glitch colour) inherited from global.css. */
[data-decode] .char.decoding,
[data-glitch-only] .char.decoding {
  color: var(--ink-mid);
}

/* Lightbox styles → lightbox.css */
/* Skip link, *:focus-visible, prefers-reduced-motion → global.css (inherited) */

/* ═══════════════════════════════════════
   SHARED CASE STUDY COMPONENTS
   Reusable across all case study pages
═══════════════════════════════════════ */

/* ─── Case Study Navigation (prev / next) ─── */
.cs-nav-projects {
  max-width: 1400px; margin: 0 auto;
  padding: 3rem 48px;
  border-top: 1px solid var(--ink);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}
.cs-nav-projects.single-next { grid-template-columns: 1fr; }
.cs-nav-projects.single-prev { grid-template-columns: 1fr; }

.cs-nav-link {
  display: flex; align-items: center; gap: 1.5rem;
  text-decoration: none; color: var(--ink);
  padding: 1.5rem 0;
  transition: all 0.3s var(--ease);
}
.cs-nav-link:hover {
  color: var(--accent-on-light);
}
.cs-nav-link--prev { flex-direction: row; }
.cs-nav-link--next { flex-direction: row; justify-content: flex-end; text-align: right; }

.cs-nav-direction {
  font-family: var(--f-mono); font-size: 0.58rem;
  text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--accent-on-light); margin-bottom: 0.35rem;
}
.cs-nav-title {
  font-family: var(--f-display); font-size: 1.25rem;
  font-weight: 600; letter-spacing: 0.05em;
  text-transform: uppercase; margin-bottom: 0.15rem;
}
.cs-nav-number {
  font-family: var(--f-mono); font-size: 0.62rem;
  color: var(--accent-on-light); letter-spacing: 0.18em;
}
.cs-nav-arrow {
  font-family: var(--f-mono); font-size: 1.5rem;
  color: var(--accent-on-light); flex-shrink: 0;
  transition: transform 0.3s var(--ease);
}
.cs-nav-link--prev:hover .cs-nav-arrow { transform: translateX(-8px); }
.cs-nav-link--next:hover .cs-nav-arrow { transform: translateX(8px); }

/* ─── Reflection Cards (Dark Mode) ─── */
/* Generous vertical padding — dark sections need breathing room around the colour-shift transition */
.cs-reflection-section {
  background: var(--ink-soft, #141414); color: var(--bg, #F0EDE8);
  margin: 0; padding: calc(var(--cs-section-gap, 3rem) * 2) 48px;
}
.cs-reflection-inner {
  max-width: 1400px; margin: 0 auto;
}
.cs-reflection-label {
  font-family: var(--f-mono); font-size: 0.68rem;
  text-transform: uppercase; letter-spacing: 0.22em;
  color: var(--accent); margin-bottom: 0.5rem;
}
.cs-reflection-title {
  font-family: var(--f-display); font-size: 2rem;
  font-weight: 700; color: var(--bg, #F0EDE8);
  margin-bottom: 2rem;
}
.cs-reflection-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
/* Column variants — add class to .cs-reflection-grid */
.cs-reflection-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.cs-reflection-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.cs-reflection-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
.cs-reflection-card {
  padding: 2rem;
  border: 1px solid rgba(240, 237, 232, 0.1);
  background: rgba(240, 237, 232, 0.03);
  opacity: 0; transition: opacity 0.6s var(--ease);
  position: relative;
}
.cs-reflection-card.in { opacity: 1; }
.cs-reflection-card::before {
  content: '';
  position: absolute; top: 0; left: 0;
  width: 3px; height: 100%;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.4s var(--ease);
}
.cs-reflection-card:hover::before { transform: scaleY(1); }
.cs-reflection-card:hover {
  border-color: rgba(0, 232, 122, 0.3);
}
.cs-reflection-card h3 {
  font-family: var(--f-display); font-size: 1.1rem;
  font-weight: 600; color: var(--bg, #F0EDE8);
  letter-spacing: 0.05em; text-transform: uppercase;
  margin-bottom: 0.75rem;
}
.cs-reflection-card p {
  font-family: var(--f-body); font-size: 0.9rem;
  line-height: 1.8; font-weight: 300;
  color: rgba(240, 237, 232, 0.6);
}

/* Closing paragraph below the reflection grid — used to wrap a Reflection
   section with a final "how was this possible" framing (e.g. AI workflow
   disclosure on case-04). Sits inside .cs-reflection-inner, after the grid.
   Spans the same width as the grid above (no max-width / centering) so it
   reads as an extension of the grid rather than an isolated callout. */
.cs-reflection-closer {
  font-family: var(--f-body);
  font-size: 0.95rem;
  line-height: 1.8;
  font-weight: 300;
  color: var(--ink-on-dark, rgba(240, 237, 232, 0.72));
  margin: var(--cs-section-gap, 3rem) 0 0;
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
}
.cs-reflection-closer strong { color: var(--bg, #F0EDE8); font-weight: 500; }

/* ─── Responsive for shared components ─── */
@media (max-width: 1024px) {
  .overview { padding-left: 0; }
  .cs-nav-projects { padding: 2rem; gap: 1rem; }
  .cs-nav-title { font-size: 1.1rem; }
  .cs-reflection-section { padding: 2.5rem 2rem; }
  .cs-reflection-grid.cols-4 { grid-template-columns: repeat(2, 1fr); }
  .cs-reflection-grid.cols-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  .cs-nav-projects {
    padding: 1.5rem 1.25rem;
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .cs-nav-link {
    padding: 1rem 0;
    gap: 0.75rem;
    justify-content: center;
    text-align: center;
  }
  .cs-nav-link--prev { flex-direction: column; }
  .cs-nav-link--next { flex-direction: column; text-align: center; justify-content: center; }
  .cs-nav-arrow { font-size: 1rem; }
  .cs-nav-direction { font-size: 0.52rem; }
  .cs-nav-title { font-size: 1rem; }
  .cs-nav-number { font-size: 0.55rem; }
  .cs-reflection-section { padding: 2rem 1.25rem; }
  .cs-reflection-grid,
  .cs-reflection-grid.cols-2,
  .cs-reflection-grid.cols-3,
  .cs-reflection-grid.cols-4 { grid-template-columns: 1fr; }
}

/* Reduced motion → handled in global.css */

/* ═════════════════════════════════════════════════════════════
   Phase Timeline — shared component for project timelines.
   3-column grid on desktop with a horizontal connector. On mobile
   the grid stacks vertically and the connector pivots 90°. Because
   card heights vary with task counts, phase-timeline.js measures
   the first/last dot centre and writes --timeline-start-mobile /
   --timeline-length-mobile so the vertical line ends exactly on
   the last dot. CSS fallback (no JS) still renders a reasonable
   line via height: calc(100% - 3.25rem).
   Originally inline in case-02; extracted 2026-04-20 alongside the
   mobile-timeline fix. Showcase twin .ds-phase-timeline lives in
   case-01.css (dark surface, scaled-down tokens).
   ═════════════════════════════════════════════════════════════ */
.phase-timeline {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 0; position: relative;
  padding-left: 3rem; padding-top: 2rem;
}
.phase-timeline::before {
  content: '';
  position: absolute;
  top: calc(2rem + 6px); left: 3rem; right: 0;
  height: 2px; background: var(--ink);
  z-index: 1;
}
.phase-card {
  position: relative; padding: 0 1.5rem 0 0;
  opacity: 0; transition: opacity 0.6s var(--ease);
}
.phase-card.in { opacity: 1; }
.phase-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--bg);
  position: relative; z-index: 2; margin-bottom: 1.25rem;
}
.phase-label {
  font-family: var(--f-mono); font-size: 0.6rem;
  color: var(--accent-on-light); letter-spacing: 0.18em;
  text-transform: uppercase; margin-bottom: 0.35rem;
}
.phase-name {
  font-family: var(--f-display); font-size: 1.1rem;
  font-weight: 600; margin-bottom: 0.5rem;
}
.phase-date {
  font-family: var(--f-mono); font-size: 0.65rem;
  color: var(--ink-dim); letter-spacing: 0.1em;
  margin-bottom: 1rem;
}
.phase-tasks { list-style: none; }
.phase-tasks li {
  font-size: 0.85rem; line-height: 1.7;
  padding-left: 1.25rem; position: relative;
  color: var(--ink-mid);
}
.phase-tasks li::before {
  content: '\2192';
  position: absolute; left: 0;
  color: var(--accent-on-light);
  font-family: var(--f-mono); font-size: 0.75rem;
}

/* Description variant — used when a phase needs prose instead of a task list
   (e.g. .phase-timeline.is-career on case-01 timeline of career stages). */
.phase-desc {
  font-size: 0.85rem; line-height: 1.7;
  color: var(--ink-mid);
  margin: 0;
}

/* Career variant — 4 stages instead of 3 phases.
   Used on case-01 ".phase-timeline.is-career". Same connector + dot system,
   wider grid on desktop, falls into mobile-stack rules below from 1024px down. */
.phase-timeline.is-career {
  grid-template-columns: repeat(4, 1fr);
}

/* Tablet — page gutter shrinks, so the internal 3rem padding-left
   is removed. Re-align the connector to span dot-centre to dot-centre. */
@media (max-width: 1024px) {
  .phase-timeline { padding-left: 0; }
  .phase-timeline::before { left: 6px; right: 6px; }
}

/* Mobile — cards stack vertically; connector pivots to a vertical line.
   Exact endpoints come from phase-timeline.js via CSS vars; CSS fallback
   keeps a sensible line (to 3.25rem before container end) if JS is off. */
@media (max-width: 768px) {
  .phase-timeline { grid-template-columns: 1fr; gap: 2rem; }
  /* .is-career variant has higher specificity than the base rule above,
     so the mobile stack needs an explicit override to actually apply. */
  .phase-timeline.is-career { grid-template-columns: 1fr; }
  /* Push card content past the vertical line; pin the dot absolutely to
     the card top-left so it sits on the line AND level with the PHASE
     label (instead of stacking above it via margin-bottom). */
  .phase-card { padding: 0 0 0 1.5rem; }
  .phase-dot {
    position: absolute;
    top: 1px;
    left: 0;
    margin: 0;
  }
  .phase-timeline::before {
    display: block;
    top: var(--timeline-start-mobile, calc(2rem + 7px));
    left: 5px;
    right: auto;
    bottom: auto;
    width: 2px;
    height: var(--timeline-length-mobile, calc(100% - 3.25rem));
  }
}

/* ═════════════════════════════════════════════════════════════
   TV Signal Loss — shared glitch effect for Restricted Areas.
   Applied to .restricted-overlay (case-02 hero) and .classified-frame
   (case-03 / case-04 deliverables) via the .tv-frame composable class.
   Config baked 2026-04-20: 2px scan · 600ms burst · 5–8s interval
   · chromatic + noise ON. No idle filter pulse (would break
   backdrop-filter on case-02). Ambient motion comes from the
   scan / noise / band layers. Replaces the Chiral Network particle
   field. See _tv-glitch-preview.html for the validated look.
   ═════════════════════════════════════════════════════════════ */

.tv-frame {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  --burst-dur: 600ms;
}

.tv-scanlines {
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0, transparent 2px,
    rgba(240, 237, 232, 0.06) 2px,
    rgba(240, 237, 232, 0.06) 3px
  );
  pointer-events: none;
  z-index: 2;
  animation: tv-scan-drift 6s linear infinite;
}
@keyframes tv-scan-drift {
  0%   { transform: translateY(0); }
  100% { transform: translateY(3px); }
}

.tv-noise {
  position: absolute; inset: -6%;
  pointer-events: none;
  z-index: 3;
  opacity: 0.08;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 1 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  animation: tv-noise-shift 0.14s steps(2) infinite;
  transition: opacity 0.3s;
}
@keyframes tv-noise-shift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-3%, 2%); }
  50%  { transform: translate(2%, -3%); }
  75%  { transform: translate(-2%, 3%); }
  100% { transform: translate(0, 0); }
}

.tv-band {
  position: absolute; left: 0; right: 0;
  height: 14%;
  top: -20%;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(240, 237, 232, 0.04) 30%,
    rgba(240, 237, 232, 0.14) 50%,
    rgba(240, 237, 232, 0.04) 70%,
    transparent 100%
  );
  pointer-events: none;
  z-index: 4;
  mix-blend-mode: overlay;
  animation: tv-band-roll 16s linear infinite;
}
@keyframes tv-band-roll {
  0%   { top: -20%; }
  100% { top: 120%; }
}

.tv-content {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 0.75rem;
  z-index: 5;
  transition: transform 0.05s;
}

.tv-frame.glitching {
  animation: tv-glitch-shake var(--burst-dur) steps(10) 1;
}
.tv-frame.glitching .tv-content {
  animation: tv-glitch-content var(--burst-dur) steps(8) 1;
}
.tv-frame.glitching .tv-noise { opacity: 0.25; }

@keyframes tv-glitch-shake {
  0%   { filter: contrast(1)   hue-rotate(0deg)   saturate(1);   transform: translate(0); }
  15%  { filter: contrast(2.2) hue-rotate(25deg)  saturate(1.6); transform: translate(-3px, 1px); }
  30%  { filter: contrast(0.5) hue-rotate(-40deg) saturate(0.4); transform: translate(2px, -2px); }
  45%  { filter: contrast(2.8) hue-rotate(60deg)  saturate(1.8); transform: translate(-1px, 3px); }
  60%  { filter: contrast(0.7) hue-rotate(-25deg) saturate(0.6); transform: translate(4px, 0); }
  75%  { filter: contrast(1.6) hue-rotate(15deg)  saturate(1.2); transform: translate(-2px, -1px); }
  90%  { filter: contrast(1.1) hue-rotate(0deg)   saturate(1);   transform: translate(1px, 0); }
  100% { filter: contrast(1)   hue-rotate(0deg)   saturate(1);   transform: translate(0); }
}
@keyframes tv-glitch-content {
  0%   { transform: translate(0)         skewX(0deg);  clip-path: inset(0 0 0 0); }
  20%  { transform: translate(-5px, 1px) skewX(-2deg); clip-path: inset(30% 0 40% 0); }
  40%  { transform: translate(4px, -2px) skewX(3deg);  clip-path: inset(10% 0 55% 0); }
  60%  { transform: translate(-3px, 3px) skewX(-1deg); clip-path: inset(50% 0 10% 0); }
  80%  { transform: translate(2px, 0)    skewX(1deg);  clip-path: inset(0 0 65% 0); }
  100% { transform: translate(0)         skewX(0deg);  clip-path: inset(0 0 0 0); }
}

/* Chromatic aberration on text — only during burst.
   Selector covers both naming conventions (case-02 restricted-*,
   case-03/04 classified-*). */
.tv-frame.glitching .restricted-badge,
.tv-frame.glitching .restricted-sub,
.tv-frame.glitching .classified-badge-inner,
.tv-frame.glitching .classified-hint {
  text-shadow:
    -2px 0 rgba(255, 51, 51, 0.85),
     2px 0 rgba(0, 229, 255, 0.85);
}

@media (prefers-reduced-motion: reduce) {
  .tv-scanlines,
  .tv-noise,
  .tv-band,
  .tv-frame.glitching,
  .tv-frame.glitching .tv-content {
    animation: none !important;
  }
}

/* ═════════════════════════════════════════════════════════════
   DELIVERABLES · MEDIA FRAME · CLASSIFIED FRAME — shared across
   case-03, case-04 (and any future case study with deliverable
   blocks, screenshots, mockups, or restricted-area placeholders).

   Pattern: 3-area grid (header / media / body). Desktop lays out
   media RIGHT · content LEFT. Mobile stacks header → media → body
   so the screenshot sits between title and copy (Rule #5:
   // Deliverable → Title → Screenshot → Body → Tags → CTA).

   Case-specific overrides (aspect-ratio changes, phone mocks,
   desktop-only CTA, wide variant, etc) live in each case-NN.css.
   ═════════════════════════════════════════════════════════════ */

/* Deliverable block */
.deliverable-block {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    'header media'
    'body   media';
  gap: 0.75rem 3rem;
  align-items: start;
  padding-left: 3rem;
  margin-bottom: calc(var(--cs-inner-gap) * 1.5);
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.deliverable-block.in { opacity: 1; }
.deliverable-header { grid-area: header; align-self: end; }
.deliverable-media  { grid-area: media;  align-self: center; position: relative; display: flex; align-items: center; justify-content: center; }
.deliverable-body   { grid-area: body;   align-self: start; }

.deliverable-label {
  font-family: var(--f-mono); font-size: 0.6rem;
  color: var(--accent-on-light); letter-spacing: 0.2em;
  text-transform: uppercase; margin-bottom: 0.75rem;
}
.deliverable-title {
  font-family: var(--f-display); font-size: 1.5rem; font-weight: 600;
  margin-bottom: 0; letter-spacing: 0.03em;
  text-transform: uppercase;
}
.deliverable-body p {
  font-size: 0.95rem; line-height: 1.8;
  font-weight: 300; margin-bottom: var(--cs-element-gap);
}
.deliverable-specs {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-bottom: var(--cs-element-gap);
}
.spec-pill {
  font-family: var(--f-mono); font-size: 0.58rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--ink);
  text-transform: uppercase; letter-spacing: 0.15em;
  color: var(--ink-mid);
}

/* CTA button — primary action (used at the end of deliverable body) */
.btn-launch {
  display: inline-flex; align-items: center; gap: 0.75rem;
  padding: 1rem 1.5rem;
  background: var(--ink); color: var(--bg);
  font-family: var(--f-mono); font-size: 0.7rem;
  letter-spacing: 0.2em; text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--ink);
  transition: all 0.3s var(--ease);
}
.btn-launch:hover {
  background: var(--accent); color: var(--ink);
  border-color: var(--accent);
}
.btn-launch .arr { transition: transform 0.3s var(--ease); }
.btn-launch:hover .arr { transform: translateX(4px); }
.btn-launch.secondary { background: transparent; color: var(--ink); }
.btn-launch.secondary:hover {
  background: var(--ink); color: var(--bg); border-color: var(--ink);
}

/* Media frame — container shell for screenshots / mockups / prototypes.
   Default 16:10 aspect-ratio; case-specific overrides (is-wide, phone-mock)
   live per-case. Corner brackets use --accent; .classified-frame overrides
   them to red (universal restricted signal). */
.media-frame {
  width: 100%;
  aspect-ratio: 16 / 10;
  background: var(--ink-soft);
  border: 1px solid var(--ink);
  position: relative;
  overflow: hidden;
}
.media-frame::before {
  content: '';
  position: absolute; top: 12px; left: 12px;
  width: 20px; height: 20px;
  border-top: 1px solid var(--accent);
  border-left: 1px solid var(--accent);
  z-index: 2;
}
.media-frame::after {
  content: '';
  position: absolute; bottom: 12px; right: 12px;
  width: 20px; height: 20px;
  border-bottom: 1px solid var(--accent);
  border-right: 1px solid var(--accent);
  z-index: 2;
}
.media-frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
/* Utility: align cover image to top (e.g. tall artwork that should anchor at the top edge) */
.media-frame img.is-top-aligned { object-position: top left; }
.media-caption {
  position: absolute; bottom: -1.75rem; left: 0;
  font-family: var(--f-mono); font-size: 0.6rem;
  color: var(--ink-mid); letter-spacing: 0.15em;
  text-transform: uppercase;
}

/* Classified frame — universal restricted signal (red #FF3333), decoupled
   from the portfolio green identity. Used by case-02 (overlay frames),
   case-03 (Figma deliverable), case-04 (Design System + Research Board). */
.classified-frame {
  border-color: rgba(255, 51, 51, 0.25);
  transition: box-shadow 0.4s ease, border-color 0.4s ease;
}
.classified-frame::before {
  border-top-color: #FF3333;
  border-left-color: #FF3333;
}
.classified-frame::after {
  border-bottom-color: #FF3333;
  border-right-color: #FF3333;
}
.classified-placeholder {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 0.75rem;
  padding: 2rem 1.5rem; /* Rule #4 — placeholder text never flush to edges */
  box-sizing: border-box;
  text-align: center;
  background: var(--ink-soft);
}
.classified-placeholder::before {
  content: '';
  position: absolute; inset: 0;
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 10px,
    rgba(255, 51, 51, 0.03) 10px,
    rgba(255, 51, 51, 0.03) 20px
  );
  pointer-events: none;
}
.classified-badge-inner {
  font-family: var(--f-mono); font-size: 0.65rem;
  padding: 0.5rem 1.25rem;
  border: 1px solid #FF3333;
  color: #FF3333;
  text-transform: uppercase; letter-spacing: 0.22em;
  position: relative;
  z-index: 2;
  animation: classifiedPulse 3s infinite;
}
.classified-hint {
  font-family: var(--f-mono); font-size: 0.55rem;
  color: rgba(240, 237, 232, 0.45);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  position: relative;
  z-index: 2;
}

.classified-frame:hover {
  border-color: rgba(255, 51, 51, 0.55);
  box-shadow: 0 0 32px rgba(255, 51, 51, 0.15),
              inset 0 0 40px rgba(255, 51, 51, 0.04);
}
.classified-frame:hover .classified-placeholder::before {
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 10px,
    rgba(255, 51, 51, 0.08) 10px,
    rgba(255, 51, 51, 0.08) 20px
  );
}
@media (prefers-reduced-motion: reduce) {
  .classified-badge-inner { animation: none; }
}

/* Mobile — stack deliverable block vertically, drop 3rem left-padding */
@media (max-width: 1024px) {
  .deliverable-block {
    grid-template-columns: 1fr;
    grid-template-areas:
      'header'
      'media'
      'body';
    gap: var(--cs-element-gap);
    padding-left: 0;
  }
}
