/**
 * About page styles.
 * Loaded only on /about — page-specific styles that do not belong in site.css.
 *
 * Relies on site.css for: custom properties, section system, buttons, skip-link,
 * nav, footer, and all shared utilities.
 * Follows CUBE CSS methodology: Composition, Utility, Block, Exception.
 *
 * Responsive Breakpoints (Desktop-First):
 * - Desktop:       1025px+ (base styles, no media query)
 * - Laptop:        max-width: 1024px
 * - Tablet:        max-width: 768px
 * - Large Mobile:  max-width: 580px  (content-driven: portrait scaling threshold)
 * - Mobile:        max-width: 480px
 */

/* ==========================================================================
   Page-Specific Custom Properties
   ========================================================================== */

:root {
  /**
   * Portrait column width — shared between the hero grid column and the portrait's
   * max-width so both values stay in sync if the portrait size is ever adjusted.
   * Used in: .about-hero__layout (grid-template-columns) and .about-hero__portrait (max-width).
   */
  --about-portrait-width: 540px;
}

/* ==========================================================================
   Composition — Layout Structure
   ========================================================================== */

/* Section 1, Hero layout — two-column asymmetric grid: photo | text */
.about-hero__layout {
  display: grid;
  grid-template-columns: var(--about-portrait-width) 1fr;
  gap: var(--space-2xl);
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

/* Section 2, Story layout — single editorial column */
.about-story__layout {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Section 3, Platforms layout — single editorial column, matches story width */
.about-platforms__layout {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Section 4, Beyond layout — heading above 3-column card grid */
.about-cards__layout {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-md);
}

/* Section 5, CTA layout — centered text block */
.about-cta__layout {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 var(--space-md);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
}

/* ==========================================================================
   Utility — Single-Purpose Classes
   ========================================================================== */

/* (none added yet) */

/* ==========================================================================
   Block — Section 1: The Mission, Hero
   ========================================================================== */

/* Photo column — positioned context for gaze element */
.about-hero__photo-col {
  position: relative;
}

/* Picture element — block so it participates in grid flow */
.about-hero__picture {
  display: block;
  position: relative;
  isolation: isolate; /* Contain the z-index: -1 pseudo within this context */
}

/**
 * Wavy highlighter border on the portrait.
 *
 * Technique: ::before pseudo-element with tertiary background sits behind the
 * portrait (z-index: -1). An SVG filter (defined in about.php) uses feTurbulence
 * to generate organic fractal noise, then feDisplacementMap warps the element's
 * pixels based on that noise — creating irregular, hand-drawn waves on all four
 * edges uniformly.
 *
 * Tuning knobs (in the about.php SVG filter definition):
 * - baseFrequency: higher = more, smaller waves (try 0.02–0.05)
 * - scale: displacement intensity — higher = more dramatic edge wobble
 * - seed: changes the random wave pattern without affecting other values
 * - inset (here): controls overall border thickness
 */
.about-hero__picture::before {
  content: '';
  position: absolute;
  inset: -24px;
  z-index: -1;
  background-color: var(--color-bg-navy); /* navy canvas (was --color-tertiary, repurposed to azure in task 6.0) */
  /* Filter defined in about.php <defs id="wavy-portrait-edge"> */
  filter: url('#wavy-portrait-edge');
}

/**
 * Portrait image — scales responsively within its 540px column.
 *
 * height: auto is required here (and on any responsive img with HTML width/height
 * attributes). The HTML attributes reserve layout space before the image loads
 * (prevents layout shift), but without height: auto the browser treats that
 * reserved height as a fixed pixel value that never scales down. The two work
 * together: HTML attributes for layout reservation, height: auto for proportional
 * scaling as width changes.
 */
.about-hero__portrait {
  max-width: var(--about-portrait-width);
  width: 100%;
  height: auto;
  display: block;
  border-radius: 6px;
}

/**
 * Spark cluster — decorative SVG accent partially overlapping the left edge
 * of the portrait. Desktop only: hidden at 1024px and below via responsive block.
 *
 * translate(-65%) shifts the cluster so ~65% of its width sits left of the
 * portrait edge and ~35% overlaps, creating a natural framing accent.
 */
.about-hero__gaze {
  position: absolute;
  left: 0;
  top: 8%;
  transform: translateX(-65%);
  width: 180px;
  pointer-events: none;
}

.about-hero__gaze-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Text column — flex column with consistent vertical rhythm */
.about-hero__text-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Eyebrow — the register (spark glyph, tiny / 700 / 0.14em, --text-accent)
   comes from .section__eyebrow (site.css), which the markup now composes
   (reclassed at 01-prd-marketing-restyle.md task 12.7). This class keeps only
   the hero's rhythm: the text column's flex gap separates the pair, so the
   baseline bottom margin is zeroed. It also remains the hero entrance
   stagger's CSS/JS hook (see the .js block below and about/hero-animations.js). */
.about-hero__eyebrow {
  margin-bottom: 0;
}

/**
 * Hero h1 headline — DM Serif Display (var(--font-accent)) per PRD req 10.
 * Weight 400 is the only available weight for DM Serif Display.
 */
.about-hero__headline {
  font-family: var(--font-accent);
  font-size: var(--font-size-6xl);
  font-weight: 400;
  line-height: 1.1;
  color: var(--color-text-light);
  margin-bottom: 0;
}

/* Body copy — muted cream, comfortable line height */
.about-hero__body {
  font-size: var(--font-size-base);
  line-height: 1.7;
  color: var(--color-text-muted-dark);
  margin-bottom: 0;
}

/* ==========================================================================
   Block — Section 2: The Story
   ========================================================================== */

/* Section heading — register (serif, 4xl, 400, +0.01em) from .section__heading
   (site.css, FR 5); this override keeps only the flex-gap rhythm: the layout's
   gap separates, so the baseline bottom margin is zeroed. */
.about-story__heading {
  margin-bottom: 0;
}

/* Body paragraphs — comfortable reading rhythm */
.about-story__body {
  font-size: var(--font-size-base);
  line-height: 1.8;
  color: var(--color-text-dark);
  margin-bottom: 0;
}

/**
 * Pull quote — editorial blockquote with orange left border accent.
 * DM Serif Display (var(--font-accent)) gives it an authoritative, personal feel.
 * Margin-top/bottom adds extra breathing room beyond the layout gap.
 */
.pull-quote {
  font-family: var(--font-accent);
  font-size: var(--font-size-3xl);
  font-style: italic;
  font-weight: 400;
  line-height: 1.35;
  color: var(--color-text-dark);
  border-left: 4px solid var(--color-primary);
  padding: var(--space-sm) 0 var(--space-sm) var(--space-md);
  margin: var(--space-sm) 0;
}

.pull-quote p {
  margin: 0;
}

/* Attribution credit — small, non-italic, de-emphasized.
   The face is reset explicitly because `.pull-quote` sets the display serif
   (`--font-accent`); without this the attribution inherits it. Was `var(--font-base)`
   until 2026-08-25 — a token that never existed (a misreach for the real
   `--font-size-base`), so the reset silently did nothing and the credit shipped
   in the serif. Caught by `tools/scripts/check-css-tokens.js`. */
.pull-quote cite {
  display: block;
  font-family: var(--font-primary);
  font-size: var(--font-size-small);
  font-style: normal;
  font-weight: 600;
  color: var(--color-text-dark);
  margin-top: var(--space-sm);
}

/* Cartoon illustration — centered block, max-width 720px */
.about-story__illustration {
  display: block;
  margin: var(--space-sm) auto;
}

/* height: auto required — see comment on .about-hero__portrait for the full explanation */
.about-story__illustration-img {
  display: block;
  max-width: 720px;
  width: 100%;
  height: auto;
  margin: 0 auto;
}

/* ==========================================================================
   Block — Section 3: Choosing the Right Approach
   ========================================================================== */

/* Section h2 heading — register from .section__heading (see .about-story__heading) */
.about-platforms__heading {
  margin-bottom: 0;
}

/* Section h3 subheading — introduces the tech stack icon group */
.about-platforms__subheading {
  font-size: var(--font-size-2xl);
  font-weight: 700;
  line-height: 1.2;
  color: var(--color-text-light);
  margin-bottom: 0;
  margin-top: var(--space-sm);
}

/* Body paragraphs — comfortable reading rhythm */
.about-platforms__body {
  font-size: var(--font-size-base);
  line-height: 1.8;
  color: var(--color-text-muted-dark);
  margin-bottom: 0;
}

/* Quiet closing line below the ledger — de-emphasized aside. The old 5.8rem
   offset existed to clear the hover-tooltip reveal; the ledger has everything
   in flow, so it sits close (12.8, operator ask). */
.about-platforms__quiet {
  font-size: var(--font-size-tiny);
  font-style: italic;
  color: var(--color-text-muted-dark);
  text-align: center;
  margin: var(--space-md) 0 0;
}

/**
 * Tech ledger — the "what I use / what it does / why I use it" chart (12.8;
 * replaced the hover-tooltip icon row: its descriptions were invisible at rest
 * on desktop, unreachable on touch above 570px, and aria-hidden to assistive
 * tech — hover is for feedback, content belongs in flow).
 * Header row and tool rows share one grid template so the columns align.
 */
.about-platforms__ledger-head,
.about-platforms__ledger {
  width: 100%;
  max-width: 82rem;
  margin: 0 auto;
  text-align: left;
}

/* The list itself — rows carry their own separators */
.about-platforms__ledger {
  list-style: none;
  padding: 0;
}

.about-platforms__ledger-head,
.about-platforms__tech-row {
  display: grid;
  grid-template-columns: 40px 12rem 1fr 1fr;
  gap: var(--space-md);
  align-items: center;
  border-bottom: 1px solid var(--border-hairline-light);
}

/* Header row — visual affordance only (aria-hidden in markup) */
.about-platforms__ledger-head {
  padding-bottom: var(--space-xs);
}

/* Column headers in the eyebrow's type treatment (type only — not a kicker, no spark) */
.about-platforms__ledger-h {
  margin: 0;
  font-size: var(--font-size-tiny);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted-dark);
}

.about-platforms__tech-row {
  padding: var(--space-sm) 0;
}

/* Icon — decorative beside its visible name (aria-hidden in markup);
   SVG brand colors are baked into each file — no fill overrides needed */
.about-platforms__tech-icon {
  display: inline-flex;
  width: 40px;
  height: 40px;
}

.about-platforms__tech-icon svg {
  width: 100%;
  height: 100%;
}

.about-platforms__tech-name {
  margin: 0;
  font-size: var(--font-size-base);
  font-weight: 700;
  color: var(--color-text-light);
}

.about-platforms__tech-what,
.about-platforms__tech-why {
  margin: 0;
  font-size: var(--font-size-small);
  line-height: 1.6;
  color: var(--color-text-muted-dark);
}

/* The "why" column reads as the aside it is */
.about-platforms__tech-why {
  font-style: italic;
}

/* ==========================================================================
   Block — Section 4: Beyond the Code
   ========================================================================== */

/* Section heading — register from .section__heading; this block-flow layout
   keeps its wider existing gap to the card grid (--space-xl over the
   baseline's --space-lg). */
.about-cards__heading {
  margin-bottom: var(--space-xl);
}

/* 3-column card grid */
.about-cards__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-lg);
}

/**
 * Discovery card — relative positioning context for the SVG border overlay.
 * Padding provides inner breathing room; the SVG border sits on top via absolute
 * positioning and does not affect the card's layout dimensions.
 */
.discovery-card {
  position: relative;
  padding: var(--space-lg) var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* Card heading */
.discovery-card__heading {
  font-size: var(--font-size-xl);
  font-weight: 700;
  line-height: 1.3;
  margin: 0;
}

/* Card body paragraphs */
.discovery-card__body {
  font-size: var(--font-size-base);
  line-height: 1.75;
  margin: 0;
}

/**
 * Hand-drawn dashed border via inline SVG (.discovery-card__border in about.php).
 *
 * Each card's SVG contains two <path> elements with the same coordinates:
 * - .discovery-card__border-dash: dashed stroke, visible at rest
 * - .discovery-card__border-draw: solid stroke, animates in on hover
 *   (stroke-dashoffset starts at 400 — the full path length — making it
 *   invisible, then transitions to 0 as the border is "drawn")
 *
 * On hover: the dashed path fades out while the solid path draws in.
 * Each card has slightly different path coordinates and dash rhythms so
 * the borders look individually hand-drawn.
 *
 * preserveAspectRatio="none" lets the paths stretch to any card height without
 * a fixed aspect ratio — but it stretches the STROKE too, non-uniformly: on a
 * card seven times wider than the 100-unit drawing the side strokes came out
 * ~9 px wide and ran under the first letter of the copy at 768 (restyle task
 * 15.7, 2026-09-01). So the paths carry vector-effect: non-scaling-stroke,
 * which keeps the stroke at its attribute width in screen pixels. That moves
 * the dash arithmetic into screen pixels as well (all three engines agree),
 * where no static value can track a perimeter that changes with the card's
 * content — so the SVG is a size container and the dash lengths below are
 * written in cqw/cqh, i.e. in the SVG's rendered size, which is the card's:
 * 200cqw + 200cqh is the perimeter. The path is ~385 units long, which is
 * what the per-card --dash / --gap rhythms are scaled against.
 *
 * See knowledge/system/design-decisions.md (SVG Draw-In Border for Cards)
 * for the full rationale.
 */

/* SVG border container — stretched to match card bounds */
.discovery-card__border {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
  /* Size container for the paths' cqw/cqh dash lengths (header comment above).
     Legal here because the element's size comes from inset: 0, never from
     content — size containment costs nothing. */
  container-type: size;
}

/* Dashed path — rest state. --dash / --gap are the rhythm in path units (the
   attribute values the markup used to carry), scaled to the rendered perimeter. */
.discovery-card__border-dash {
  fill: none;
  stroke: var(--color-primary);
  vector-effect: non-scaling-stroke;
  --dash: 5;
  --gap: 3.5;
  stroke-dasharray: calc((200cqw + 200cqh) * var(--dash) / 385) calc((200cqw + 200cqh) * var(--gap) / 385);
}

.about-cards__grid .discovery-card:nth-child(2) .discovery-card__border-dash {
  --dash: 4;
  --gap: 4.5;
}

.about-cards__grid .discovery-card:nth-child(3) .discovery-card__border-dash {
  --dash: 6.5;
  --gap: 3;
}

/* Draw-in path — starts invisible, animates in on hover. The first pair is the
   fallback an engine without container units keeps: a dash and offset longer
   than any card's perimeter, so the hover still draws the whole border, only
   with the visible part of the transition compressed. The second pair is the
   exact perimeter and wins wherever cqw/cqh resolve. */
.discovery-card__border-draw {
  fill: none;
  stroke: var(--color-primary);
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 4000;
  stroke-dashoffset: 4000;
  stroke-dasharray: calc(200cqw + 200cqh);
  stroke-dashoffset: calc(200cqw + 200cqh);
}

@media (prefers-reduced-motion: no-preference) {
  .discovery-card__border-dash {
    transition: opacity 200ms ease;
  }

  .discovery-card__border-draw {
    transition: stroke-dashoffset 600ms ease;
  }

  .discovery-card:hover .discovery-card__border-dash {
    opacity: 0;
  }

  .discovery-card:hover .discovery-card__border-draw {
    stroke-dashoffset: 0;
  }
}

/* Reduced motion: snap to drawn state without animation */
@media (prefers-reduced-motion: reduce) {
  .discovery-card:hover .discovery-card__border-draw {
    stroke-dashoffset: 0;
  }
}

/* ==========================================================================
   Block — Section 5: Closing CTA
   ========================================================================== */

/* CTA heading — register from .section__heading (see .about-story__heading) */
.about-cta__heading {
  margin-bottom: 0;
}

/* CTA body copy */
.about-cta__body {
  font-size: var(--font-size-base);
  line-height: 1.7;
  color: var(--color-text-muted-dark);
  max-width: 56ch;
  margin-bottom: 0;
}

/* Button group — flex row with gap, centered */
.about-cta__buttons {
  display: flex;
  flex-direction: row;
  gap: var(--space-sm);
  justify-content: center;
  flex-wrap: wrap;
}

/* ==========================================================================
   Exception — kicker rhythm inside the flex-gap layouts
   ========================================================================== */

/* The three flex-column layouts space every child with a --space-md (20px)
   gap; .section__eyebrow's own --space-sm (10px) bottom margin would compound
   that to 30px between kicker and heading. The negative margin nets the pair
   to the baseline's 10px while every other pair keeps the 20px gap.
   (Section eyebrows added at 01-prd-marketing-restyle.md task 12.7; the
   block-flow .about-cards__layout needs nothing — the eyebrow's natural
   margin applies there.) */
.about-story__layout .section__eyebrow,
.about-platforms__layout .section__eyebrow,
.about-cta__layout .section__eyebrow {
  margin-bottom: calc(-1 * var(--space-sm));
}

/* ==========================================================================
   Exception — JS animation initial states (.js class)
   ========================================================================== */

/**
 * Section 1 hero elements start hidden when JS is available.
 * hero-animations.js reveals them via the double-rAF sequence on load.
 * Without .js (JS disabled or failed): elements are fully visible by default.
 * No data-anim attributes on Section 1 — the scroll observer must not target these.
 */
.js .about-hero__eyebrow,
.js .about-hero__headline,
.js .about-hero__body,
.js .about-hero__picture {
  opacity: 0;
  transform: translateY(20px);
}

/* ==========================================================================
   Responsive — max-width: 1024px (Laptop)
   ========================================================================== */

@media (max-width: 1024px) {

  /* --- Section 1: Hero --- */

  /* Collapse two-column grid to single column; photo stacks above text */
  .about-hero__layout {
    grid-template-columns: 1fr;
  }

  /* Center the photo column content */
  .about-hero__photo-col {
    display: flex;
    justify-content: center;
  }

  /* Hide the gaze element at laptop/tablet/mobile — desktop only */
  .about-hero__gaze {
    display: none;
  }

  /* --- Section 3: Beyond the Code --- */

  /*
   * 2+1 arrangement: two cards side-by-side in the first row, third card
   * centered below at half the grid width so it doesn't stretch full-width.
   */
  .about-cards__grid {
    grid-template-columns: 1fr 1fr;
  }

  .about-cards__grid .discovery-card:last-child {
    grid-column: 1 / -1;
    max-width: 50%;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
  }

}

/* ==========================================================================
   Responsive — max-width: 768px (Tablet)
   ========================================================================== */

@media (max-width: 768px) {

  /* --- Section 2: The Story --- */

  /* Constrain the picture element to match the img's max-width so both share the same bounds */
  .about-story__illustration {
    max-width: 720px;
    width: 100%;
  }

  /* --- Section 3: Choosing the Right Approach --- */

  /* Ledger collapses: header row hidden, each row becomes icon | name with the
     two text lines flowing under the name in the second column */
  .about-platforms__ledger-head {
    display: none;
  }

  .about-platforms__tech-row {
    grid-template-columns: 40px 1fr;
    row-gap: 0.6rem;
  }

  .about-platforms__tech-what,
  .about-platforms__tech-why {
    grid-column: 2;
  }

  /* --- Section 4: Beyond the Code --- */

  /* Single column at tablet — remove the 2+1 centering constraint */
  .about-cards__grid {
    grid-template-columns: 1fr;
  }

  .about-cards__grid .discovery-card:last-child {
    grid-column: auto;
    max-width: none;
  }

  /* --- Section 5: Closing CTA --- */

  /* Buttons stack vertically at tablet */
  .about-cta__buttons {
    flex-direction: column;
    align-items: center;
  }

}

/* ==========================================================================
   Responsive — max-width: 580px (Large Mobile / Landscape Phone)
   ========================================================================== */

/* --- Section 1: Hero --- */

/*
 * Cap portrait and its picture wrapper at 380px (~65% of viewport) so the portrait
 * doesn't dominate the screen at this size. Constraining the picture element keeps
 * the ::before pseudo-element (wavy border) aligned to the portrait bounds.
 * The border inset is also reduced from 24px to 16px to stay proportional at the
 * smaller portrait size.
 */
@media (max-width: 580px) {
  .about-hero__picture {
    max-width: 380px;
    width: 100%;
  }

  .about-hero__portrait {
    max-width: 380px;
  }

  .about-hero__picture::before {
    inset: -16px;
  }

}

/* ==========================================================================
   Responsive — max-width: 480px (Mobile)
   ========================================================================== */

/* (No additional Section 1 overrides at 480px) */
