/*
 * components.css — Amanda Morgan Portfolio
 * Applies design system tokens to base elements and all page components.
 * Mirrors the structure of portfolio-wireframe.html.
 * Edit this file directly or regenerate via Claude Code.
 * ─────────────────────────────────────────────────────────────────────────────
 */


@font-face {
  font-family: 'King Basil Lite';
  src: url('assets/fonts/King-Basil-Lite.otf') format('opentype');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}


/* ─── Reset & base ───────────────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

/* display:flex + flex-direction:column here, paired with .cs-footer's
   margin-top:auto below, is the sticky-footer pattern — on a page shorter than the
   viewport, the footer still sits flush to the bottom instead of trailing right
   after the content. Works regardless of how many content sections a given
   template has between nav and footer (case-study.php has two — main + .cs-more-
   studies — front-page.php has one), since margin-top:auto on the footer alone
   consumes whatever space is left, with no changes needed to nav (position:fixed,
   already out of flow) or the content sections themselves. */
body {
  max-width: 2500px;
  margin: 0 auto;
  padding: 0;
  background-color: var(--color-surface-page);
  background-image: radial-gradient(circle, rgba(180,175,165,0.25) 1.5px, transparent 1.5px);
  background-size: 32px 32px;
  color: var(--color-text-primary);
  font-family: var(--font-standard);
  font-size: 15px;
  line-height: var(--leading-normal);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--text-h1-family);
  font-weight: var(--text-h1-weight);
  line-height: var(--text-h1-leading);
  color: var(--color-text-primary);
}

p {
  font-family: var(--font-standard);
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
}

a {
  color: inherit;
  text-decoration: none;
}

img {
  max-width: 100%;
  display: block;
}

/* ─── Image skeleton loading state ──────────────────────────────────────────
   Every deferred image (loading="lazy" — case study/feature thumbnails, in-
   body screenshots) sitewide: an animated shimmer shows via the <img>'s own
   background while it's loading (the img itself is opacity:0, so the shimmer
   is what's actually visible), then fades to the real image once JS
   (ampm_image_skeleton_js, functions.php) adds .is-loaded on load. Scoped by
   attribute selector so it applies automatically everywhere without touching
   any template markup.
   Note: this only shows if the image's box already has real height before
   load — true for .base-module__image img (sized by its flex/grid parent)
   but NOT for images like .cs-consideration__img, which have no set height
   and currently collapse to 0px until their own content defines it (a
   separate, pre-existing layout-shift issue worth fixing with real
   width/height attributes, not something this skeleton alone solves). */
img[loading="lazy"] {
  transition: opacity 0.25s ease;
}
img[loading="lazy"]:not(.is-loaded) {
  opacity: 0;
  background: linear-gradient(
    100deg,
    var(--color-surface-secondary) 25%,
    var(--color-surface-primary) 50%,
    var(--color-surface-secondary) 75%
  );
  background-size: 200% 100%;
  animation: ampm-skeleton-shimmer 1.4s ease-in-out infinite;
}
@keyframes ampm-skeleton-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  img[loading="lazy"]:not(.is-loaded) {
    animation: none;
  }
}


/* ─── Utility classes ────────────────────────────────────────────────────── */
.label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.label-accent {
  color: var(--color-accent);
}

.serif {
  font-family: var(--font-display);
}

.wire-box {
  border: var(--border-width-default) solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  background: rgba(245,243,238,0.85);
}

.wire-box-dashed {
  border: 1.5px dashed var(--color-border-default);
  border-radius: var(--radius-sm);
  background: rgba(245,243,238,0.6);
}

.annotation {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-accent);
  position: relative;
  padding-left: 12px;
}

.annotation::before {
  content: '→';
  position: absolute;
  left: 0;
  font-size: 10px;
}

/* Tags */
.tag {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  padding: 5px 10px;
  border: var(--border-width-default) solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
}

.tag-active {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: var(--color-accent-subtle);
}


/* ─── Buttons ────────────────────────────────────────────────────────────── */
.btn-primary {
  font-family: var(--button-font-family);
  font-size: 14px;
  font-weight: var(--button-font-weight);
  padding: var(--space-component-md) var(--space-component-xl);
  background: var(--color-action-primary);
  color: var(--color-action-primary-text);
  border: none;
  border-radius: var(--button-radius);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: opacity 0.2s;
}

.btn-primary:hover {
  background: var(--color-action-primary-hover);
}

.btn-ghost {
  font-family: var(--button-font-family);
  font-size: 14px;
  font-weight: var(--button-font-weight);
  padding: var(--space-component-md) var(--space-component-xl);
  background: var(--color-action-secondary);
  color: var(--color-action-secondary-text);
  border: var(--border-width-default) solid var(--color-action-secondary-border);
  border-radius: var(--button-radius);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}

.btn-ghost:hover {
  border-color: var(--color-action-secondary-hover);
  color: var(--color-action-primary-text);
  background: var(--color-action-secondary-hover);
}

/* Tertiary — text-only with arrow, no background or border */
.btn-tertiary {
  font-family: var(--button-font-family);
  font-size: 14px;
  font-weight: var(--button-font-weight);
  background: transparent;
  border: none;
  padding: 0;
  color: var(--color-action-secondary-text);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: color 0.2s;
}
.btn-tertiary::after {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M 7.5 15 L 12.5 10 L 7.5 5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M 7.5 15 L 12.5 10 L 7.5 5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  flex-shrink: 0;
}
.btn-tertiary:hover { color: var(--color-action-secondary-hover); }


/* ─── BaseModule (Figma "🧩 Components" page, component set 128:252) ────────────
   Single global source of truth for BaseModule and every one of its variants —
   Default, Default Right, Default Left, Feature 1, List 1, List 2, H1Text — plus the
   dot scroll indicator used alongside it. Unscoped on purpose: this is genuine
   Figma-Components-page content, not page-specific layout, so per the 2026-09-11
   architecture decision (see feedback_css_file_by_figma_page memory) it belongs here
   and only here, regardless of which template(s) currently instantiate it.
   Was previously split into two independently-diverging copies — a full unscoped
   version in surrealism.css (front-page only) and a second, `.cs-more-studies`-scoped
   parallel copy here covering only the Feature 1 subset — which had already drifted
   apart (different gap value, different title token, different image-cropping
   approach) before being reconciled by hand. Local aliases from both source files
   (surrealism.css's --deep/--ink/--ink-muted/--ink-ghost/--gold/--sans, case-study.css's
   --cs-border) are normalized to their real tokens.css equivalents throughout, since
   this file must work standalone on any page without assuming either page's private
   :root aliases are present. The one genuinely page-specific thing left behind in
   each page's own file is the carousel container (.work-grid, sizing/scroll
   mechanics) — that's each page's own "Horizontal List" Figma frame, not this
   component set, so it stays in surrealism.css / case-study.css respectively. */
.base-module {
  position: relative;
  background: var(--color-surface-primary);
  border-radius: var(--size-8);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Grid span / tall helpers — kept for future grid contexts, not currently used by
   any live variant (all current cards render in a single-row horizontal carousel). */
.base-module--span-2 { grid-column: span 2; }
.base-module--span-3 { grid-column: span 3; }
.base-module--tall   { grid-row: span 2; }

/* Shape (optional) — Figma: Shape component inside each card, toggle with
   .base-module--has-shape. Feature 1 and H1Text both replace this CSS-gradient
   version with an inline SVG mesh gradient instead — see their own shape rules
   below — so this generic version is only live for variants that don't (none,
   currently; kept for parity with the component's full variant set). */
.base-module__shape {
  position: absolute;
  width: 240px;
  height: 240px;
  border-radius: 48px;
  background: linear-gradient(160deg, var(--color-accent-tertiary) 40%, var(--color-accent-secondary) 70%);
  transform: rotate(18deg);
  bottom: -80px;
  right: -60px;
  opacity: 0.3;
  pointer-events: none;
  z-index: 0;
}
/* Nudge content above the shape */
.base-module--has-shape .base-module__header,
.base-module--has-shape .base-module__body,
.base-module--has-shape .base-module__actions {
  position: relative;
  z-index: 1;
}

/* Header (optional) — Figma: Header, avatar + identity + close. Toggle with
   .base-module--has-header. Not used by any live variant currently. */
.base-module__header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--color-border-ghost);
  flex-shrink: 0;
}
.base-module__avatar {
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  border: 1px solid var(--color-border-ghost);
}
.base-module__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  position: relative;
  z-index: 1;
}
.base-module__avatar-shape {
  position: absolute;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  background: linear-gradient(160deg, var(--color-accent-tertiary) 40%, var(--color-accent-secondary) 70%);
  transform: rotate(18deg);
  top: 7px;
  left: -7px;
  z-index: 0;
  pointer-events: none;
}
.base-module__identity {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.base-module__name {
  font-family: 'King Basil Lite', serif;
  font-size: 13px;
  font-weight: 300;
  color: var(--color-text-primary);
  white-space: nowrap;
}
.base-module__role {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

/* Body — Figma: Body frame has padding:8px all sides across all variants */
.base-module__body {
  display: flex;
  flex: 1;
  min-height: 0;
  padding: var(--size-8);
}

/* Content column — always present. Figma: Content frame adds its own 8px left/right
   padding on top of the card's own padding (unlike the image, which is full-bleed
   within just the card padding), plus a minWidth:120 floor. */
.base-module__content {
  flex: 1;
  padding: 0 var(--size-8);
  display: flex;
  flex-direction: column;
  gap: var(--size-8);
  min-width: var(--size-120);
}

/* Overline — category | label tags above the title. Matches Figma: Overline frame
   with Typography instances. */
.base-module__overline {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-body-small-size, 12px);
  font-weight: var(--weight-200);
  color: var(--color-tag-text);
  flex-wrap: wrap;
}
.base-module__overline-sep { color: var(--color-border-ghost); }

.base-module__title {
  font-family: var(--font-standard);
  font-weight: var(--weight-600);
  color: var(--color-text-primary);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.base-module__desc {
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-300);
  color: var(--color-text-secondary);
  line-height: var(--leading-relaxed);
}

/* Divider — optional horizontal rule before skill tags */
.base-module__divider {
  border: none;
  border-top: 1px solid var(--color-border-default);
  margin: 4px 0;
}

/* Skill / method tags — small pill badges below divider */
.base-module__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 4px 0;
}
.base-module__tag {
  font-size: var(--text-body-small-size, 12px);
  font-weight: var(--weight-200);
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--color-info-text);
}

/* Metric — large stat shown on Featured cards. Matches Figma: 00% / METRIC LABEL
   HERE on Work Card/Type=Featured. Not used by any live variant currently. */
.base-module__metric {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  padding: 24px 32px;
  flex-shrink: 0;
  text-align: right;
}
.base-module__metric-value {
  font-family: var(--font-standard);
  font-size: clamp(40px, 5vw, 72px);
  font-weight: var(--weight-600);
  color: var(--color-accent-text);
  line-height: 1;
  letter-spacing: -0.02em;
}
.base-module__metric-label {
  font-size: 9px;
  font-weight: var(--weight-600);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent-text);
  margin-top: 8px;
}

/* Image — optional; position depends on variant */
.base-module__image {
  overflow: hidden;
  flex-shrink: 0;
}
.base-module__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}
.base-module:hover .base-module__image img { transform: scale(1.03); }

/* Actions row (optional) — Figma: Action Row with up to 3 BTN instances. Omit the
   element in markup to hide the row entirely. */
.base-module__actions {
  display: flex;
  gap: var(--size-8);
  flex-wrap: wrap;
  align-items: center;
  padding: var(--size-8);
  border-top: 1px solid var(--color-border-ghost);
  position: relative;
  z-index: 1;
}
.base-module__actions .btn-primary,
.base-module__actions .btn-ghost {
  font-size: 11px;
  padding: 8px 16px;
}

/* ─── Variants ───────────────────────────────────────────────────────────── */

/* Default — Figma: Work Card/Default. Wide text-and-metric card, no image/header.
   Not used by any live variant currently. */
.base-module--default {
  flex-direction: column;
}
.base-module--default .base-module__body {
  flex-direction: row;
  align-items: center;
}
.base-module--default .base-module__title {
  font-size: var(--text-h1-size);
}

/* Default Right — Figma: BaseModule=Default Right. Content left, image right,
   vertically centered. Not used by any live variant currently. */
.base-module--default-right .base-module__body {
  flex-direction: row;
  align-items: center;
  gap: 16px;
  padding: var(--size-8);
}
.base-module--default-right .base-module__image {
  flex: 1;
  min-height: 160px;
}
.base-module--default-right .base-module__title {
  font-size: var(--text-h1-size);
}

/* Default Left — Figma: BaseModule=Default Left. Mirror of Default Right. Not used
   by any live variant currently. */
.base-module--default-left .base-module__body {
  flex-direction: row-reverse;
  align-items: center;
  gap: 16px;
  padding: var(--size-8);
}
.base-module--default-left .base-module__image {
  flex: 1;
  min-height: 160px;
}
.base-module--default-left .base-module__title {
  font-size: var(--text-h1-size);
}

/* Feature 1 — Figma: BaseModule=Feature 1 (218:770). Used by front-page's Featured
   Work carousel and case-study's "More Case Studies" carousel.
   Padding/gap/font-sizes pinned to their sm-tier literal value (not the responsive
   custom properties the base rules above use) — confirmed via the Plugin API that
   this component's entire Responsive variable collection is explicitly pinned to
   "sm" mode (explicitVariableModes on 218:770), so nothing in this card should
   scale with viewport width, regardless of which page it's placed on. */
.base-module--feature-1 {
  padding: var(--size-8);
  gap: var(--size-16);
  min-height: var(--size-200);
}
.base-module--feature-1 .base-module__overline {
  color: var(--color-text-secondary);
  text-transform: uppercase;
  font-size: var(--size-12);
  min-height: 15px; /* Figma's real measured Overline frame height — reserves the same box whether or not this variant shows overline text, so titles align with H1Text's title (which has no overline text but keeps the frame present, same box height) */
}
.base-module--feature-1 .base-module__title {
  font-size: var(--size-20);
  font-weight: var(--text-h4-weight, 500);
}
/* min-height:100px (Figma: Description Typography, Hug + minHeight:100 — Body
   itself is already Fill via .base-module__body's flex:1) reserves the same
   description-block height regardless of how short a given card's copy is, so
   tags/actions land at the same y across every Feature 1/H1Text card — same
   alignment technique as the Overline min-height fix above, one tier down. */
.base-module--feature-1 .base-module__desc {
  font-size: var(--size-16);
  font-weight: 200;
  line-height: 1.25em;
  color: var(--color-text-secondary);
  min-height: 100px;
}
.base-module--feature-1 .base-module__tag {
  font-size: var(--size-12);
}
.base-module--feature-1 .base-module__divider {
  display: none;
}
.base-module--feature-1 .base-module__actions {
  border-top: none;
  padding: var(--size-8) 0;
  gap: var(--size-16);
}
/* The "View Case Study" tertiary button's own horizontal padding wasn't showing —
   .btn-tertiary is shared sitewide with padding:0 by design (text+icon only, no
   button chrome elsewhere), but Figma's Feature 1 Action Row BTN instance carries
   real Padding/Button Horizontal Padding (12px at sm, confirmed via boundVariables
   on a live instance's Button Base). Scoped here rather than touching the shared
   .btn-tertiary base rule. */
.base-module--feature-1 .base-module__actions .btn-tertiary {
  padding: 0 var(--size-12);
  /* Lifted above .base-module__stretched-link (z-index 2, below) so hovering the
     actual visible button still triggers .btn-tertiary's own :hover color change,
     rather than the stretched link swallowing the hover state everywhere. */
  position: relative;
  z-index: 3;
}
.base-module--feature-1 .base-module__body {
  flex-direction: column;
  padding: 0;
  gap: var(--size-16);
}
/* Image container (Figma "faImage", 241:1304): min-height:147/max-height:148 (same
   floor/ceiling pair as H1Text's "Hello" slot below, so both occupy the same band).
   Fills its parent, aligns content top-center, and does NOT clip — the image is
   allowed to bleed past the container's edges if it's wider than the card once
   scaled to the container's height. Replaces the old fixed-height/cover/cropped
   approach entirely. */
.base-module--feature-1 .base-module__image {
  width: 100%;
  min-height: 147px;
  max-height: 148px;
  overflow: visible;
  flex-shrink: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
}
/* Image itself: aspect-ratio locked, height fills the container — width is
   whatever that implies, not forced, so it can be narrower OR wider than the card
   without distortion (still bounded by the outer .base-module's own
   overflow:hidden at the card edge).
   object-fit: contain is required here, not just decorative — the base
   .base-module__image img rule above sets object-fit: cover, and this rule
   never used to reset it. That was invisible for images narrower than the
   card, but for every real feature image (wider than the card at 147px tall,
   by design — that's the whole point of "allowed to bleed") the base img{}
   rule's max-width:100% caps the auto width below the aspect-ratio-correct
   value, and the leftover cover then crops the image to fill that
   now-too-narrow box — the top-of-mockup clipping the user reported live.
   contain guarantees the full image is always visible, matching Figma
   (clipsContent:false on this frame) and the "nothing is cropped" comment
   that was here before but wasn't actually true until now. */
.base-module--feature-1 .base-module__image img {
  width: auto;
  height: 100%;
  object-fit: contain;
  display: block;
}
/* Cancels the base .base-module:hover .base-module__image img zoom — the image no
   longer being cropped/cover-fit makes a hover zoom look wrong (it would push the
   already-bleeding edges further out). */
.base-module--feature-1:hover .base-module__image img {
  transform: none;
}
/* Feature 1 shape: inline SVG mesh gradient matching Figma exactly (Figma uses
   feGaussianBlur stdDeviation=154.1 on each solid-filled sub-shape, not a CSS
   gradient). SVG fill attributes reference CSS token variables for light/dark mode
   support. Shared with H1Text below — both variants use the identical technique. */
.base-module--feature-1 .base-module__shape,
.base-module--h1text .base-module__shape {
  inset: 0;
  width: 100%;
  height: 100%;
  background: none;
  transform: none;
  opacity: 1;
}
.base-module--feature-1 .base-module__shape::before,
.base-module--feature-1 .base-module__shape::after,
.base-module--h1text .base-module__shape::before,
.base-module--h1text .base-module__shape::after {
  display: none;
}
/* Oversized + centered rather than an exact inset:0/100% fit — the export's own
   clip-path is a ROUNDED SQUARE ROTATED -83°, which doesn't reach the corners of
   its own 657×657 square canvas (rotating a square inward like that leaves the
   canvas's 4 corners transparent). A plain cover-fit of that canvas onto the card
   just reproduces those same transparent corners inside the card, visible as gaps.
   Scaling the whole svg up to 220% and centering pushes the rotated shape's own
   edges safely past all 4 sides of the card, so what actually shows inside the
   card is solid artwork everywhere — the overscan itself is invisible, clipped by
   the outer .base-module's own overflow:hidden (not this element's, which doesn't
   need its own clip). */
.base-module--feature-1 .bm-shape-svg,
.base-module--h1text .bm-shape-svg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 220%;
  height: 220%;
  overflow: hidden;
}

/* Hover/focus state (Figma: Feature1-Hover 871:115222, H1Text-Hover — same shadow
   spec confirmed by the user for both). Triggers on :focus-within too, not just
   :hover, so tabbing to a card's button also shows the hover treatment, per the
   user's "on hover or focus" request. Two changes: a drop shadow on the whole
   card, and two of the shape's gradient blobs recolor (confirmed against the
   user's exported SVGs — Feature1's/H1Text's hover Shape has identical geometry to
   the non-hover Shape, only 2 of its 4 fills change: one tertiary→secondary, one
   secondary→Color/Status/Info/Default; the other tertiary and secondary shapes are
   unchanged). */
/* Base state's box-shadow is explicit (same offset/blur/spread, 0 alpha) rather
   than left unset — transitioning box-shadow from the implicit `none` isn't
   reliably smooth across browsers (some just snap), but interpolating the alpha
   channel of two matching shadow values always animates cleanly. */
.base-module--feature-1,
.base-module--h1text {
  box-shadow: 0px 2px 2px 0px rgba(42, 42, 42, 0);
  transition: box-shadow 0.25s ease;
}
.base-module--feature-1:hover,
.base-module--feature-1:focus-within,
.base-module--h1text:hover,
.base-module--h1text:focus-within {
  box-shadow: 0px 2px 2px 0px rgba(42, 42, 42, 0.15);
}
/* The recolor is an opacity crossfade, not a `fill` transition: each shifting
   shape (ellipse, first blob path) has a second, hover-only duplicate sitting
   exactly on top of it in the exported SVG (ampm_bm_shape_svg(), functions.php) —
   already the hover color, opacity:0 by default, fading to opacity:1 on hover.
   Directly transitioning `fill` looked instant rather than smooth in practice: both
   shapes sit under a heavy Gaussian blur filter (stdDeviation:77), and most
   browsers have to recompute that blur every frame while `fill` is mid-transition,
   which is expensive enough that the color change reads as a snap. Fading a
   already-blurred static layer's opacity in has none of that per-frame cost. */
.bm-shape-hover-secondary,
.bm-shape-hover-info {
  opacity: 0;
  transition: opacity 0.25s ease;
}
.base-module--feature-1:hover .bm-shape-hover-secondary,
.base-module--feature-1:focus-within .bm-shape-hover-secondary,
.base-module--h1text:hover .bm-shape-hover-secondary,
.base-module--h1text:focus-within .bm-shape-hover-secondary,
.base-module--feature-1:hover .bm-shape-hover-info,
.base-module--feature-1:focus-within .bm-shape-hover-info,
.base-module--h1text:hover .bm-shape-hover-info,
.base-module--h1text:focus-within .bm-shape-hover-info {
  opacity: 1;
}

/* Whole-card click target (Feature 1 only — see front-page.php/case-study.php for
   why H1Text doesn't get one: it has two buttons with two different destinations,
   no single canonical target for the rest of the card to share). Sits above the
   shape/body/actions z-index:1 layer but below the visible "View Case Study"
   button (z-index:3, set on .btn-tertiary above), so the button keeps its own
   independent hover/focus behavior while every other point on the card shares its
   href. aria-hidden + tabindex="-1" in the markup keep it out of the accessible
   name/tab order — the real button is the one accessible entry point. */
.base-module__stretched-link {
  position: absolute;
  inset: 0;
  z-index: 2;
}

/* H1Text — Figma: BaseModule=H1Text (839:107211). Used only by front-page's
   Featured Work carousel, first position — replaces the old standalone hero. Same
   card shell as Feature 1 (padding, min-height, shape background) but the image
   slot is replaced by a large hand-lettered "Hello" headline (see .base-module__h1
   below), above the usual title/desc/tags/actions content. Padding/gap pinned to
   sm, same reasoning as Feature 1 — 839:107211 has the identical
   explicitVariableModes Responsive→sm override. */
.base-module--h1text {
  padding: var(--size-8);
  gap: var(--size-16);
  min-height: var(--size-200);
}
/* Empty by design (see front-page.php markup — an aria-hidden div with no text) —
   reserves the same 15px box as Feature 1's real overline text so titles line up
   across both card types. This is Figma's own solution too: the Overline *frame*
   stays present even when its child Typography instances are hidden. */
.base-module--h1text .base-module__overline {
  color: var(--color-text-primary);
  text-transform: uppercase;
  font-size: var(--size-12);
  min-height: 15px;
}
.base-module--h1text .base-module__title {
  font-size: var(--size-20);
  font-weight: var(--text-h4-weight, 500);
}
.base-module--h1text .base-module__desc {
  font-size: var(--size-16);
  font-weight: 200;
  line-height: 1.25em;
  color: var(--color-text-secondary);
  min-height: 100px;
}
.base-module--h1text .base-module__tag {
  font-size: var(--size-12);
}
.base-module--h1text .base-module__divider {
  display: none;
}
.base-module--h1text .base-module__body {
  flex-direction: column;
  padding: 0;
  gap: 16px;
}
.base-module--h1text .base-module__actions {
  border-top: none;
  padding: var(--size-8) 8px; /* sm-tier, pinned */
}

/* H1 headline block — replaces the image slot. Figma: H1 frame, min-height/
   max-height 147/148 (same band as Feature 1's faImage above), 8px left/right
   padding (own padding, on top of the card's own — matches Content's identical
   treatment). Content is the designer's own hand-lettered artwork, Hello.svg
   (Figma 864:115137), inlined via ampm_hello_svg() in front-page.php with its fill
   swapped to currentColor so it follows this element's color and still adapts to
   light/dark mode. svg width is auto (not 100%) so its own aspect ratio drives it
   once height is resolved in the 147–148 range — at the card's ~232px content
   width the svg's natural size would otherwise scale down well below its 312×148
   original, reading too small; any resulting overflow is clipped by the outer
   .base-module's own overflow:hidden, same as Feature 1's unclipped image above. */
.base-module__h1 {
  min-height: 147px;
  max-height: 148px;
  padding: 0 8px;
  margin: 0;
  color: var(--color-text-primary);
}
.base-module__h1 svg {
  display: block;
  width: auto;
  min-height: 147px;
  max-height: 148px;
}

/* Action Row icons — H1Text's "Connect" button and the About Hero's "Connect on
   LinkedIn" button share the exact same .btn-ghost + leading LinkedIn glyph
   treatment (same component, same destination, same button). Scoped to these two
   variants rather than added to the base .btn-primary/.btn-ghost rules, since every
   other use of those classes on the site has no icon. Extended to the password
   modal's Action Row (Figma: same trailing-chevron Submit / leading-LinkedIn-icon
   Request buttons). */
.base-module--h1text .btn-primary,
.pw-modal__actions .btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.base-module--h1text .btn-primary::after,
.pw-modal__actions .btn-primary::after {
  content: '';
  display: inline-block;
  width: 16px;
  height: 16px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M 7.5 15 L 12.5 10 L 7.5 5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M 7.5 15 L 12.5 10 L 7.5 5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  flex-shrink: 0;
}
.base-module--h1text .btn-ghost,
.base-module--about-hero .btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.base-module--h1text .btn-ghost::before,
.base-module--about-hero .btn-ghost::before,
.pw-modal__actions .btn-tertiary::before {
  content: '';
  display: inline-block;
  width: 16px;
  height: 16px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 19 18'%3E%3Cpath d='M12.4667 5.7998C13.7928 5.7998 15.0646 6.32659 16.0022 7.26427C16.9399 8.20195 17.4667 9.47372 17.4667 10.7998V16.6331H14.1334V10.7998C14.1334 10.3578 13.9578 9.93385 13.6452 9.62129C13.3327 9.30873 12.9087 9.13314 12.4667 9.13314C12.0247 9.13314 11.6008 9.30873 11.2882 9.62129C10.9756 9.93385 10.8 10.3578 10.8 10.7998V16.6331H7.46671V10.7998C7.46671 9.47372 7.9935 8.20195 8.93118 7.26427C9.86886 6.32659 11.1406 5.7998 12.4667 5.7998Z' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3Cpath d='M4.13338 6.63314H0.800049V16.6331H4.13338V6.63314Z' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3Cpath d='M2.46672 4.13314C3.38719 4.13314 4.13338 3.38695 4.13338 2.46647C4.13338 1.546 3.38719 0.799805 2.46672 0.799805C1.54624 0.799805 0.800049 1.546 0.800049 2.46647C0.800049 3.38695 1.54624 4.13314 2.46672 4.13314Z' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 19 18'%3E%3Cpath d='M12.4667 5.7998C13.7928 5.7998 15.0646 6.32659 16.0022 7.26427C16.9399 8.20195 17.4667 9.47372 17.4667 10.7998V16.6331H14.1334V10.7998C14.1334 10.3578 13.9578 9.93385 13.6452 9.62129C13.3327 9.30873 12.9087 9.13314 12.4667 9.13314C12.0247 9.13314 11.6008 9.30873 11.2882 9.62129C10.9756 9.93385 10.8 10.3578 10.8 10.7998V16.6331H7.46671V10.7998C7.46671 9.47372 7.9935 8.20195 8.93118 7.26427C9.86886 6.32659 11.1406 5.7998 12.4667 5.7998Z' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3Cpath d='M4.13338 6.63314H0.800049V16.6331H4.13338V6.63314Z' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3Cpath d='M2.46672 4.13314C3.38719 4.13314 4.13338 3.38695 4.13338 2.46647C4.13338 1.546 3.38719 0.799805 2.46672 0.799805C1.54624 0.799805 0.800049 1.546 0.800049 2.46647C0.800049 3.38695 1.54624 4.13314 2.46672 4.13314Z' stroke='black' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  flex-shrink: 0;
}
/* LinkedIn button switched from .btn-ghost to .btn-tertiary (no border), per
   the user's updated Figma — reuses .btn-tertiary's borderless look but with
   the LinkedIn glyph leading (::before, above) instead of its default trailing
   chevron arrow (suppressed here, since that arrow means "View Case Study"
   elsewhere on the site, not "Request"). */
.pw-modal__actions .btn-tertiary {
  gap: 4px;
}
.pw-modal__actions .btn-tertiary::after {
  content: none;
}

/* About — Figma: BaseModule=About (1019:93530). Used only by about.php's Highlights
   grid (career roles, education, personal fun-facts). Same card shell/shape as
   Feature 1/H1Text but simpler: no tags, divider, actions, or stretched-link (this
   component has none of those in Figma — the Tags/Action Row frames aren't present
   on the instance at all, not just hidden). Image is a small logo/icon SVG, not a
   photo — shown centered/contained rather than cropped to fill. */
.base-module--about {
  position: relative;
  padding: var(--size-8);
  gap: var(--size-16);
  border-radius: var(--size-8);
  background: var(--color-surface-primary);
}
/* Gradient stroke (Figma: 1px, OUTSIDE alignment, linear gradient Color/Border/
   Subtle → Color/Accent/Tertiary — user changed the 1st stop from Accent/Default to
   Border/Subtle, #f9f9f2, and the 2nd from Accent/Secondary to Accent/Tertiary,
   #9ed1ff, both confirmed matching --color-border-subtle/--color-accent-tertiary
   exactly). Angle verified by exporting the component as SVG and reading the actual
   <linearGradient> coordinates directly (x1=1,y1=384.7 → x2=346,y2=4.3, i.e.
   bottom-left to top-right) rather than hand-decoding the raw gradientTransform
   matrix a second time — computes to ~42deg in CSS terms; the earlier 135deg guess
   had the diagonal backwards (top-left-to-bottom-right instead of bottom-left-to-
   top-right). CSS can't stroke a gradient directly. First attempt used inset:-1px
   to approximate "outside" alignment, but the base .base-module rule sets
   overflow:hidden, which clipped anything extending past the card's own edge — the
   stroke was rendering, just invisible. Fixed to inset:0 (visually indistinguishable
   from true outside alignment at 1px) using the exact mask technique already
   confirmed working for .cs-scroll-top::after in case-study.css (content-box clip,
   -webkit-mask-composite only — no plain `mask` shorthand, which conflicted with
   mask-composite in the first attempt). */
.base-module--about::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(42deg, var(--color-border-subtle) 0%, var(--color-accent-tertiary) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.base-module--about .base-module__body {
  flex-direction: column;
  padding: 0;
  gap: 0;
}
/* faImage (outer) and AboutAssets (inner) containers: both width:100%/height:100%
   of the 184px-tall image band (Figma: faImage width/height fill, AboutAssets
   width/height fill inside it) — see .base-module__image-inner below for the inner
   container. The svg itself is height:100%/width:auto, aspect-ratio locked, NOT
   object-fit:cover — same "don't crop, let it bleed, outer overflow:hidden clips
   it" technique already used by .base-module--feature-1's image. */
.base-module--about .base-module__image {
  width: 100%;
  height: 184px;
  overflow: hidden;
}
.base-module--about .base-module__image-inner {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  /* Left-aligned for every card except the 2 wide ones (see --about-wide override
     below), matching Figma exactly rather than a uniform centered treatment. */
  justify-content: flex-start;
}
.base-module--about .base-module__image img {
  width: auto;
  height: 100%;
  display: block;
  transition: none;
}
.base-module--about:hover .base-module__image img {
  transform: none;
}
.base-module--about .base-module__content {
  padding: var(--size-8);
  gap: var(--size-8);
}
/* Verified via API: label/separator/dates are all the same Color/Text/Secondary,
   ExtraLight 200, UPPERCASE, 0 letter-spacing in Figma — the shared base
   .base-module__overline-sep rule colors "|" with --color-border-ghost instead,
   which read as an inconsistent color against the label/dates text; overridden
   here so all 3 segments match exactly. */
.base-module--about .base-module__overline {
  color: var(--color-text-secondary);
  font-size: var(--size-12);
  text-transform: uppercase;
  min-height: 15px;
}
.base-module--about .base-module__overline-sep {
  color: var(--color-text-secondary);
}
.base-module--about .base-module__title {
  font-size: var(--size-20);
  font-weight: var(--weight-500);
}
/* Single-line description (Figma: Description Typography, fixed 20px height) — no
   min-height reservation needed like Feature 1/H1Text, since there's no
   tags/actions row below that needs consistent alignment across cards. Several
   cards (education, personal fun-facts) have no description at all — markup omits
   the <p> entirely for those rather than rendering an empty one. */
.base-module--about .base-module__desc {
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-200);
  color: var(--color-text-secondary);
  line-height: var(--leading-normal);
}
/* "Wide" modifier — the last 2 Highlights cards (Nature Enthusiast, Volunteer) span
   half the grid width each at lg+ instead of a normal 1/5 column (see about.css for
   the grid-column spans that make this layout happen). No internal layout change:
   confirmed via the Plugin API that the card's Body frame is layoutMode:VERTICAL,
   layoutWrap:NO_WRAP in Figma — same vertical stack as every other About card, just
   wider, not a row layout with image beside content. Image is centered (not
   left-aligned like every other card) per the user's explicit correction. */
.base-module--about-wide .base-module__image-inner {
  justify-content: center;
}

/* About Hero — Figma: BaseModule=abouthero (1032:120496). Used once, at the top of
   about.php. No side image or decorative Shape at ANY viewport width (confirmed on
   both the 600px and 1440px Figma instances — the Image/Shape frames are hidden in
   both), so unlike every other BaseModule hero variant on the site, this one is
   text-only: full-width Content column, tag pills, a single button. No card
   background either (overrides the base .base-module fill) — this variant blends
   directly into the page rather than reading as a surface. */
.base-module--about-hero {
  background: none;
}
.base-module--about-hero .base-module__body {
  flex-direction: column;
  padding: var(--size-16) var(--padding-section);
}
/* Figma: abouthero > Body > Content max-width 1000px on the 1440px instance — the
   text column stays a fixed maximum width rather than stretching edge-to-edge on
   wide viewports. */
.base-module--about-hero .base-module__content {
  max-width: 1000px;
  padding: 0;
  gap: var(--size-20);
}
.base-module--about-hero .base-module__title {
  font-family: var(--font-standard);
  font-size: var(--text-h1-display-size);
  font-weight: var(--text-h1-display-weight);
  line-height: var(--text-h1-display-leading);
  letter-spacing: -0.02em;
  color: var(--color-text-primary);
}
.base-module--about-hero .base-module__desc {
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-200);
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
}
.base-module--about-hero .base-module__actions {
  border-top: none;
  padding: 0 var(--padding-section) var(--size-24);
}

/* About Hero, image variant — Figma: same BaseModule=abouthero component (Image
   frame is hidden on About's own instance, per the comment above, but visible on
   the Coming Soon page's instance, 1106:98315). Modifier follows the existing
   .base-module--has-shape convention: an optional sub-feature flag, not a new
   component. Row layout with wrap so it degrades to stacked on narrow phones
   instead of needing an explicit breakpoint switch (only one Figma reference
   width, 559px, was provided — no separate mobile/desktop variants to match). */
.base-module--about-hero.base-module--has-image .base-module__body {
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--size-32);
}
.base-module--about-hero.base-module--has-image .base-module__content {
  flex: 1 1 320px;
}
/* Actions nested inside Content here (Figma: "Jump BTNs" lives inside the Content
   frame, not as a body-level sibling like About's own instance) — .content is
   already flex-column, so this just stacks below the desc with no extra padding
   (the padding:0 var(--padding-section) above is for the sibling-of-content
   placement About uses; wrong here since Content already has its own padding). */
.base-module--about-hero.base-module--has-image .base-module__content .base-module__actions {
  padding: var(--size-8) 0 0;
  border-top: none;
}
/* Chevron-left leading icon (mirrors .btn-tertiary's default trailing chevron
   horizontally) — Figma's "Back to Home" BTN instance uses a leading
   "Chevron left" icon, not the usual trailing "View Case Study" arrow. */
.base-module--about-hero.base-module--has-image .base-module__actions .btn-tertiary::after {
  content: none;
}
.base-module--about-hero.base-module--has-image .base-module__actions .btn-tertiary::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M 12.5 15 L 7.5 10 L 12.5 5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M 12.5 15 L 7.5 10 L 12.5 5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  flex-shrink: 0;
}
/* Illustration — Figma's own SVG (ComingSoon_catcomputercoffee.svg) already
   includes its circular backdrop baked in, so no separate .base-module__shape
   decoration is needed here (unlike Feature-1/H1Text cards). */
.base-module--about-hero .base-module__image {
  flex: 1 1 240px;
  max-width: 280px;
  display: flex;
  justify-content: center;
}
.base-module--about-hero .base-module__image img {
  width: 100%;
  height: auto;
  display: block;
}
/* Cancels the base .base-module:hover .base-module__image img zoom (line 480)
   — harmless before this hero had an image at all, but now that it does,
   hovering anywhere in this (non-clickable, not a case-study link) hero was
   scaling the illustration up like a card. Same fix already used for
   .base-module--feature-1 below. */
.base-module--about-hero:hover .base-module__image img {
  transform: none;
}

/* "Explore Case Studies" carousel section — shared wrapper for the label +
   work-grid + work-dots pattern used at the end of pages that aren't
   themselves a case study (About, Coming Soon). Genuinely identical, byte for
   byte, to about.css's .about-explore-studies and case-study.css's
   .cs-more-studies (case study pages' own "More Case Studies" carousel) —
   those two were each built page-scoped before this pattern's reuse across
   pages was confirmed by a real second/third Figma instance (Coming Soon,
   1105:97131 "Other Case Studies"). Not consolidated into this one shared
   class retroactively to avoid touching two already-shipped pages in the same
   pass as a new one; worth doing as a follow-up cleanup. */
.explore-case-studies {
  background: var(--color-surface-primary);
  padding: var(--space-section-large) var(--padding-section);
  max-width: none;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--size-24);
}
.explore-case-studies__label {
  display: block;
  font-family: var(--font-standard);
  font-size: var(--text-overline-size);
  font-weight: var(--text-overline-weight);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-primary);
}
.explore-case-studies .work-grid {
  display: flex;
  flex-direction: row;
  gap: var(--size-16);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  margin-right: calc(-1 * var(--padding-section));
  padding-right: var(--padding-section);
}
.explore-case-studies .work-grid::-webkit-scrollbar { display: none; }
.explore-case-studies .work-grid .base-module {
  flex-shrink: 0;
  width: var(--size-264);
  scroll-snap-align: start;
}

/* List 1 — Figma: BaseModule=List 1. Tall card, content only (no side image). Not
   used by any live variant currently. */
.base-module--list-1 .base-module__body {
  flex-direction: column;
}
.base-module--list-1 .base-module__title {
  font-size: var(--text-h1-size);
}

/* List 2 — Figma: BaseModule=List 2. Medium-tall, content only, shape positioned
   top-right. Not used by any live variant currently. */
.base-module--list-2 .base-module__body {
  flex-direction: column;
}
.base-module--list-2 .base-module__title {
  font-size: var(--text-h1-size);
}
.base-module--list-2 .base-module__shape {
  top: -60px;
  right: -60px;
  bottom: auto;
}

/* Dot scroll indicator (Figma 836:107056) — unscoped: identical regardless of which
   page's carousel it's paired with. Pairing/behavior script: functions.php
   (ampm_work_dots_js), which measures each .work-grid's actual card stride at
   runtime instead of hardcoding it, so it works for any card width without
   per-instance JS. */
.work-dots {
  display: flex;
  flex-direction: row;
  gap: 12px;
  margin-top: var(--size-24);
}
/* Set by ampm_work_dots_js (functions.php) whenever every card already fits in the
   grid without scrolling — dots only make sense as a scroll-position indicator. */
.work-dots.is-idle {
  display: none;
}
.work-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: none;
  padding: 0;
  cursor: pointer;
  background: var(--color-accent-subtle);
  transition: background 0.2s ease;
  flex-shrink: 0;
}
.work-dot--active {
  background: var(--color-action-primary);
}

/* BaseModule responsive overrides — moved from surrealism.css (2026-09-11 cleanup),
   since these modify BaseModule component-set selectors. Both target unused
   variants (span-2/3/tall grid helpers, Default Right/Left) — inert today, kept for
   parity with the component's full variant set. */
@media (max-width: 1439px) {
  .base-module--span-2, .base-module--tall { grid-column: span 2; grid-row: span 1; }
  .base-module--span-3 { grid-column: span 2; }
}
@media (max-width: 1023px) {
  .base-module--span-2, .base-module--span-3, .base-module--tall { grid-column: span 1; grid-row: span 1; }
  .base-module--default-right .base-module__image,
  .base-module--default-left .base-module__image { width: 40%; }
}

/* ─── Nav ────────────────────────────────────────────────────────────────── */

/* nav.am-nav's real rendered height, per breakpoint — was only expressed as
   hardcoded numbers on body::before below; now a shared variable so anything that
   needs to clear the fixed nav (e.g. front-page's .work-section margin-top) can
   reference the same value instead of re-deriving/approximating it separately.
   Collapsed to 2 tiers 2026-09-25 (was 3: default/1439/1023) to match nav's own
   padding/hamburger breakpoints, which collapsed the same way when lg's real
   min-width (1024px) replaced the old 1440px number — see tokens.css's
   responsive-breakpoint-thresholds fix. */
:root {
  --nav-height: 81px;
}
@media (max-width: 1023px) { :root { --nav-height: 69px; } }

/* Nav backdrop — z-index separator so the diamond shape (10000) sits
   between this layer (9999) and interactive nav content (10001).
   Transparent; the OnScroll glass blur is applied to nav.am-nav directly
   so it blurs all content below z-index 10001, including z-index 10000 hero elements. */
body::before {
  content: '';
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--nav-height);
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  z-index: 9999;
  pointer-events: none;
}

/* Nav bar */
nav.am-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px var(--padding-section);
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 10001;
  background: transparent;
  border: none !important;
  transition: background 0.3s ease, backdrop-filter 0.3s ease, -webkit-backdrop-filter 0.3s ease;
}

/* OnScroll: glass effect matches Figma OnScroll variant (GLASS radius:55).
   Applied to nav.am-nav (z-index 10001) so it blurs all content below it,
   including z-index 10000 hero elements that body::before (9999) cannot reach. */
body.is-scrolled nav.am-nav {
  background: rgba(0, 0, 0, 0.004);
  backdrop-filter: blur(55px);
  -webkit-backdrop-filter: blur(55px);
}

/* Nav mark (logo + identity) */
nav.am-nav .nav-mark {
  text-decoration: none !important;
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  border-radius: 40px 40px 4px 40px;
}
/* Hover: Color/Accent/Subtle fill behind the avatar+identity, per the user's
   Figma hover examples (1100:95323, "logoframe" 1100:95651) — per-corner
   radii confirmed via the Plugin API (40/40/4/40, not a uniform pill;
   bottom-right updated 2px→4px, background updated Text/Inverse→Surface/
   Tertiary→Accent/Subtle, all per the user's own Figma edits). Zero padding
   matches Figma exactly (logoframe's own padding is 0), so this hugs the
   avatar+text tightly rather than growing the nav-mark's box on hover. */
nav.am-nav .nav-mark:hover {
  background: var(--color-accent-subtle);
}

nav.am-nav .nav-avatar-wrap {
  position: relative;
  flex-shrink: 0;
}

nav.am-nav .nav-avatar {
  position: relative;
  width: 40px !important;
  height: 40px !important;
  border-radius: 50% !important;
  overflow: hidden !important;
  z-index: 1;
}
nav.am-nav .nav-avatar img {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
nav.am-nav .nav-avatar-shape {
  position: absolute;
  width: 56px;
  height: 56px;
  border-radius: 13px;
  background: linear-gradient(160deg, var(--color-accent-tertiary) 40%, var(--color-accent-secondary) 70%);
  transform: rotate(18deg);
  top: 17px;
  left: -18px;
  z-index: 0;
  pointer-events: none;
}

nav.am-nav .nav-identity {
  display: flex !important;
  flex-direction: column !important;
  gap: 0 !important;
  flex: 1 !important;
  min-width: 0 !important;
  overflow: visible !important;
}
nav.am-nav .nav-name {
  font-family: var(--font-display) !important;
  font-style: normal !important;
  font-size: 16px !important;
  font-weight: 300 !important;
  color: var(--color-text-primary) !important;
  line-height: 1.56 !important;
  letter-spacing: 0.01em !important;
  text-transform: none !important;
  white-space: nowrap !important;
  display: block !important;
  width: auto !important;
  height: auto !important;
  border: none !important;
  border-radius: 0 !important;
}
nav.am-nav .nav-title {
  font-family: var(--font-standard) !important;
  font-size: 12px !important;
  font-weight: 200 !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  color: var(--color-text-primary) !important;
  line-height: 1 !important;
  white-space: nowrap !important;
  display: block !important;
  width: auto !important;
  height: auto !important;
  border: none !important;
  border-radius: 0 !important;
  /* Figma's Frame 7 (219:2811) uses a -6px item spacing between name/title —
     CSS gap can't go negative, so this reproduces the same overlap via
     margin instead (confirmed: title's own y=19 starts 6px before name's
     y=0+height:25=25 bottom edge). */
  margin-top: -6px !important;
}

/* Hamburger (sm/md < 1440px) */
.nav-hamburger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  color: var(--color-text-primary);
  flex-shrink: 0;
}
/* Hover: Color/Accent/Subtle circular fill, per Figma's hover examples
   (1100:95339 "menu" — cornerRadius 31 on a 24x24 box, clamped to a full
   circle by Figma itself; 50% reproduces the same result). */
.nav-hamburger:hover {
  color: var(--color-text-primary);
  background: var(--color-accent-subtle);
  border-radius: 50%;
}

/* Nav links: hidden by default (mobile), shown at lg+ */
nav.am-nav .nav-links {
  display: none !important;
  list-style: none !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* Mobile dropdown — toggled by JS */
nav.am-nav .nav-links.is-open {
  display: flex !important;
  flex-direction: column !important;
  gap: 0 !important;
  position: absolute !important;
  top: 100% !important;
  left: 0 !important;
  right: 0 !important;
  background: color-mix(in srgb, var(--color-surface-page) 96%, transparent) !important;
  backdrop-filter: blur(16px) !important;
  -webkit-backdrop-filter: blur(16px) !important;
  border-bottom: 1px solid var(--color-border-default) !important;
  padding: 8px var(--padding-section) 20px !important;
}

nav.am-nav .nav-links a {
  font-family: var(--font-standard) !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  color: var(--color-text-primary) !important;
  text-decoration: none !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  transition: color 0.2s;
  display: block !important;
  padding: 12px 0 !important;
  border-bottom: 1px solid var(--color-border-default) !important;
}
nav.am-nav .nav-links li:last-child a { border-bottom: none !important; }
nav.am-nav .nav-links a:hover { color: var(--color-text-primary) !important; }

/* lg+ (≥ 1024px): inline links, hide hamburger. justify-content:space-between
   (matches the base nav.am-nav rule, but restated explicitly here since it's what
   actually pushes .nav-links to the far right edge of the bar at this breakpoint —
   was flex-start+a fixed 48px gap, which packed the links right next to the logo
   instead of aligning them to the right per the updated Figma component. Threshold
   corrected 2026-09-25, was 1440px — see tokens.css's responsive-breakpoint-
   thresholds fix; padding below collapses to 1 narrow-tier step (was 2) to match. */
@media (min-width: 1024px) {
  .nav-hamburger { display: none; }
  nav.am-nav {
    justify-content: space-between;
  }
  nav.am-nav .nav-links {
    display: flex !important;
    flex-direction: row !important;
    gap: 32px !important;
    position: static !important;
    background: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    padding: 0 !important;
  }
  /* Underline-on-hover: per the user's Figma hover examples (1100:95323), the
     line is a border-bottom on the whole link's padded container (confirmed
     via the Plugin API — Button Base/BTN instances there all have
     strokeBottomWeight:1, strokeTopWeight:0, Color/Text/Primary, with
     12px/8px padding), not text-decoration on the text run itself. Padding
     added here to match that container size; border reserved as transparent
     at rest so hover doesn't shift layout.
     li:last-child included explicitly — the mobile dropdown's own
     `li:last-child a { border-bottom: none }` (divider cleanup, above) is
     unscoped to that breakpoint and otherwise leaks in here, killing
     border-style on whichever link happens to be last ("Connect on
     LinkedIn") so no hover color could ever make it visible. */
  nav.am-nav .nav-links a,
  nav.am-nav .nav-links li:last-child a {
    padding: 8px 12px !important;
    border-bottom: 1px solid transparent !important;
  }
  /* li:last-child a:hover needed as its own selector, not just a:hover — the
     resting li:last-child a rule above has HIGHER specificity (3 type
     selectors: nav, li, a) than plain a:hover (2: nav, a), so on the last
     link (Connect on LinkedIn) it kept winning for border-bottom-color even
     while hovered, no matter what a:hover said. This matches/exceeds that
     specificity so hover actually wins there too. */
  nav.am-nav .nav-links a:hover,
  nav.am-nav .nav-links li:last-child a:hover {
    border-bottom-color: var(--color-text-primary) !important;
  }
}

/* Responsive padding */
@media (max-width: 1023px) {
  nav.am-nav { padding: 14px var(--padding-section); }
}


/* ─── Hero ───────────────────────────────────────────────────────────────── */
.hero {
  padding: 80px 40px 64px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-stack-xl);
  max-width: var(--container);
  margin: 0 auto;
  align-items: start;
}

.hero-left {
  position: relative;
}

.hero-eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-component-lg);
  margin-bottom: var(--space-stack-lg);
}

.hero-eyebrow-line {
  flex: 1;
  height: 1px;
  background: var(--color-border-subtle);
  max-width: 48px;
}

.hero-name {
  font-family: var(--text-display-family);
  font-size: var(--text-display-size);
  font-weight: var(--text-display-weight);
  line-height: 0.95;
  letter-spacing: -0.02em;
  color: var(--color-text-primary);
  margin-bottom: var(--space-stack-lg);
  animation: fadeUp 0.6s ease both;
}

.hero-name em {
  font-style: italic;
  color: var(--color-text-secondary);
}

.hero-bio {
  font-size: 16px;
  line-height: var(--leading-relaxed);
  color: var(--color-text-secondary);
  max-width: 380px;
  margin-bottom: var(--space-stack-xl);
  animation: fadeUp 0.6s 0.1s ease both;
}

.hero-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-component-sm);
  margin-bottom: var(--space-stack-xl);
  animation: fadeUp 0.6s 0.15s ease both;
}

.hero-cta-row {
  display: flex;
  gap: var(--space-stack-md);
  align-items: center;
  animation: fadeUp 0.6s 0.2s ease both;
}

/* Hero right */
.hero-right {
  position: relative;
  animation: fadeUp 0.7s 0.25s ease both;
}

.hero-figma-frame {
  width: 100%;
  aspect-ratio: 16 / 10;
  border: var(--border-width-default) solid var(--color-border-subtle);
  background: rgba(255,255,255,0.5);
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-sm);
}

.figma-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  position: absolute;
  inset: 0;
}

.figma-icon {
  width: 32px;
  height: 32px;
  opacity: 0.4;
}

.hero-figma-frame iframe {
  width: 100%;
  height: 100%;
  border: none;
  position: absolute;
  inset: 0;
}

.figma-label {
  position: absolute;
  top: -11px;
  left: 12px;
  background: var(--color-surface-page);
  padding: 0 8px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.hero-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--color-border-subtle);
  border: var(--border-width-default) solid var(--color-border-subtle);
  margin-top: var(--space-stack-md);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.stat {
  background: var(--color-surface-page);
  padding: var(--space-component-lg);
  text-align: center;
}

.stat-num {
  font-family: var(--font-display);
  font-size: 28px;
  line-height: 1;
  display: block;
  margin-bottom: var(--space-stack-xs);
  color: var(--color-text-primary);
}

.stat-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}


/* ─── Section wrappers ───────────────────────────────────────────────────── */
section,
.wp-block-group {
  padding: var(--space-section) 40px;
  max-width: var(--container);
  margin: 0 auto;
}

.section-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-stack-md);
  margin-bottom: var(--space-stack-xl);
  padding-bottom: var(--space-stack-md);
  border-bottom: var(--border-width-default) solid var(--color-border-subtle);
}

.section-title {
  font-family: var(--text-h2-family);
  font-size: var(--text-h2-size);
  font-weight: var(--text-h2-weight);
  line-height: var(--text-h2-leading);
  letter-spacing: -0.01em;
  color: var(--color-text-primary);
}

.section-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-text-secondary);
  margin-left: auto;
}

.section-divider,
hr {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  border: none;
  border-top: var(--border-width-default) solid var(--color-border-subtle);
}


/* ─── Case studies ───────────────────────────────────────────────────────── */
.case-grid {
  display: grid;
  gap: 2px;
}

.case-card {
  display: grid;
  grid-template-columns: 80px 1fr 1fr auto;
  gap: 0;
  background: var(--color-border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
  transition: transform 0.2s;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
}

.case-card:hover {
  transform: translateY(-1px);
}

.case-card:hover .case-preview {
  background: rgba(212,79,46,0.05);
}

.case-num-col {
  background: var(--color-surface-page);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--card-padding-md) var(--space-component-md);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-border-default);
  border-right: var(--border-width-default) solid var(--color-border-subtle);
  gap: var(--space-component-sm);
}

.case-num-vert {
  writing-mode: vertical-rl;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: 9px;
  color: var(--color-border-default);
}

.case-info {
  background: var(--color-surface-page);
  padding: 28px 32px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-component-sm);
}

.case-title {
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.2;
  color: var(--color-text-primary);
}

.case-desc {
  font-size: 13px;
  color: var(--color-text-secondary);
  line-height: var(--leading-relaxed);
  max-width: 340px;
}

.case-tags {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: var(--space-stack-xs);
}

.case-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  padding: 3px 8px;
  border: var(--border-width-default) solid var(--color-border-subtle);
  color: var(--color-text-secondary);
  border-radius: 1px;
}

.case-tag-accent {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: var(--color-accent-subtle);
}

.case-preview {
  background: rgba(255,255,255,0.5);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 28px 24px;
  border-left: var(--border-width-default) solid var(--color-border-subtle);
  transition: background 0.2s;
}

.preview-bar {
  height: 8px;
  background: var(--color-border-subtle);
  border-radius: var(--radius-sm);
}

.preview-bar-short { width: 60%; }
.preview-bar-med   { width: 80%; }

.preview-block {
  height: 48px;
  background: var(--color-border-subtle);
  border-radius: var(--radius-sm);
  margin-top: var(--space-stack-xs);
}

.case-meta {
  background: var(--color-surface-page);
  padding: 28px 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-left: var(--border-width-default) solid var(--color-border-subtle);
  min-width: 140px;
}

.case-metric {
  font-family: var(--font-display);
  font-size: 24px;
  display: block;
  line-height: 1;
  margin-bottom: 2px;
  color: var(--color-text-primary);
}

.case-metric-label {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

.case-arrow {
  font-size: 18px;
  color: var(--color-accent);
  font-family: var(--font-mono);
  margin-top: var(--space-component-sm);
  display: block;
  transition: transform 0.2s;
}

.case-card:hover .case-arrow {
  transform: translateX(4px);
}


/* ─── Process steps ──────────────────────────────────────────────────────── */
.process-steps {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0;
  background: var(--color-border-subtle);
  border: var(--border-width-default) solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.process-step {
  background: var(--color-surface-page);
  padding: 20px 16px;
  border-right: var(--border-width-default) solid var(--color-border-subtle);
  position: relative;
}

.process-step:last-child {
  border-right: none;
}

.process-connector {
  position: absolute;
  right: -1px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-accent);
  background: var(--color-surface-page);
  padding: 2px 4px;
  line-height: 1;
}

.process-step-num {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--color-border-default);
  letter-spacing: var(--tracking-wider);
  margin-bottom: var(--space-component-sm);
  text-transform: uppercase;
}

.process-step-name {
  font-family: var(--font-display);
  font-size: 15px;
  margin-bottom: 6px;
  line-height: 1.3;
  color: var(--color-text-primary);
}

.process-step-desc {
  font-size: 11px;
  color: var(--color-text-secondary);
  line-height: var(--leading-relaxed);
}


/* ─── Figma section ──────────────────────────────────────────────────────── */
.figma-section {
  background: rgba(255,255,255,0.35);
  border-top: var(--border-width-default) solid var(--color-border-subtle);
  border-bottom: var(--border-width-default) solid var(--color-border-subtle);
}

.figma-section-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 64px 40px;
}

.figma-tabs {
  display: flex;
  gap: 0;
  border: var(--border-width-default) solid var(--color-border-subtle);
  border-bottom: none;
  width: fit-content;
}

.figma-tab {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  padding: 8px 16px;
  border: none;
  background: transparent;
  color: var(--color-text-secondary);
  cursor: pointer;
  border-right: var(--border-width-default) solid var(--color-border-subtle);
  transition: background 0.2s, color 0.2s;
}

.figma-tab:last-child {
  border-right: none;
}

.figma-tab.active {
  background: var(--color-text-primary);
  color: var(--color-surface-page);
}

.figma-tab:not(.active):hover {
  background: rgba(255,255,255,0.5);
  color: var(--color-text-primary);
}

.figma-url-input {
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 10px 16px;
  border: var(--border-width-default) solid var(--color-border-subtle);
  background: var(--color-surface-page);
  color: var(--color-text-primary);
  outline: none;
  width: 100%;
  transition: border-color 0.2s;
  border-radius: var(--input-radius);
}

.figma-url-input:focus {
  border-color: var(--color-text-primary);
}

.figma-url-input::placeholder {
  color: var(--color-border-default);
}

.figma-embed-btn {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 10px 20px;
  background: var(--color-text-primary);
  color: var(--color-surface-page);
  border: none;
  cursor: pointer;
  white-space: nowrap;
  transition: opacity 0.2s;
  border-radius: var(--radius-sm);
}

.figma-embed-btn:hover {
  opacity: 0.85;
}

.embed-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.embed-row .figma-url-input {
  flex: 1;
}

.figma-embed-frame {
  width: 100%;
  height: 640px;
  border: var(--border-width-default) solid var(--color-border-subtle);
  background: rgba(255,255,255,0.5);
  position: relative;
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.figma-embed-frame iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.figma-empty {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  text-align: center;
}

.figma-empty-icon {
  width: 48px;
  height: 48px;
  border: 1.5px dashed var(--color-border-default);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  opacity: 0.5;
}

.figma-controls {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  margin-bottom: 16px;
  align-items: center;
}


/* ─── Philosophy pillars ─────────────────────────────────────────────────── */
.pillars-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2px;
  background: var(--color-border-subtle);
  border: var(--border-width-default) solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.pillar {
  background: var(--color-surface-page);
  padding: var(--card-padding-md) 20px;
  display: flex;
  flex-direction: column;
  gap: var(--space-component-sm);
  transition: background 0.2s;
}

.pillar:hover {
  background: rgba(255,255,255,0.8);
}

.pillar-num {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-accent);
  letter-spacing: var(--tracking-wider);
}

.pillar-title {
  font-family: var(--font-display);
  font-size: 17px;
  line-height: 1.3;
  color: var(--color-text-primary);
}

.pillar-desc {
  font-size: 12px;
  color: var(--color-text-secondary);
  line-height: var(--leading-relaxed);
  flex: 1;
}

.pillar-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--color-border-default);
  padding-top: var(--space-component-sm);
  border-top: var(--border-width-default) solid var(--color-border-subtle);
}


/* ─── About ──────────────────────────────────────────────────────────────── */
.about-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-stack-xl);
  align-items: start;
}

.about-quote {
  font-family: var(--font-display);
  font-size: clamp(24px, 3vw, 38px);
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin-bottom: var(--space-stack-lg);
  color: var(--color-text-primary);
}

.about-quote em {
  color: var(--color-text-secondary);
  font-style: italic;
}

.about-body {
  font-size: 14px;
  color: var(--color-text-secondary);
  line-height: var(--leading-loose);
}

.about-right {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.about-list-item {
  display: grid;
  grid-template-columns: 24px 1fr;
  gap: var(--space-component-md);
  padding: var(--space-component-lg);
  background: rgba(255,255,255,0.4);
  border: var(--border-width-default) solid var(--color-border-subtle);
  border-radius: var(--radius-sm);
  align-items: baseline;
}

.about-list-num {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-accent);
  letter-spacing: var(--tracking-wider);
}

.about-list-text {
  font-size: 13px;
  line-height: var(--leading-relaxed);
  color: var(--color-text-secondary);
}

.about-list-text strong {
  color: var(--color-text-primary);
  font-weight: var(--weight-500);
}


/* ─── Contact ────────────────────────────────────────────────────────────── */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-stack-xl);
  align-items: center;
}

.contact-big {
  font-family: var(--font-display);
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-primary);
}

.contact-links {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.contact-link-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-component-lg) 20px;
  border: var(--border-width-default) solid var(--color-border-subtle);
  background: rgba(255,255,255,0.4);
  text-decoration: none;
  color: var(--color-text-primary);
  border-radius: var(--radius-sm);
  transition: background 0.2s, border-color 0.2s, color 0.2s;
  gap: var(--space-stack-md);
}

.contact-link-row:hover {
  background: var(--color-text-primary);
  color: var(--color-surface-page);
  border-color: var(--color-text-primary);
}

.contact-link-row:hover .contact-link-arrow {
  color: var(--color-surface-page);
}

.contact-link-row:hover .contact-link-val {
  color: rgba(245,243,238,0.7);
}

.contact-link-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
}

.contact-link-val {
  font-size: 14px;
  color: var(--color-text-secondary);
}

.contact-link-arrow {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--color-accent);
}


/* ─── Footer ─────────────────────────────────────────────────────────────── */
footer,
.site-footer {
  border-top: var(--border-width-default) solid var(--color-border-subtle);
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--card-padding-md) 40px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

footer p,
.site-footer p {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: var(--tracking-wider);
  color: var(--color-border-default);
  text-transform: uppercase;
}

/* Site-wide branded footer bar ("Amanda Morgan | Design Portfolio | year") — used on every
   template. Overrides the generic footer/.site-footer rules above: those apply site-wide by
   tag name, so .cs-footer's class selector wins on every shared property, but properties it
   doesn't declare (border-top, max-width, margin) would otherwise fall through uncontested —
   explicitly zeroed out here rather than left to chance. Was previously case-study.css-only
   and duplicated (with different, wrong values) in surrealism.css for the front page; both of
   those still exist but are harmlessly overridden now that every template uses this class. */
.cs-footer {
  background: var(--color-surface-page);
  border-top: none;
  max-width: none;
  margin: auto 0 0; /* top:auto — sticky-footer pattern, pushes this to the bottom of a flex-column body when the page's content is shorter than the viewport */
  padding: var(--padding-section); /* Figma 845:114135: all 4 sides bound to Padding/Section, was a fixed 24px vertical */
  display: flex;
  justify-content: flex-start;
  align-items: center;
}
.cs-footer p {
  width: 100%;
  font-family: var(--font-standard);
  font-size: var(--text-body-small-size);
  font-weight: var(--weight-300);
  letter-spacing: 0.06em;
  color: var(--color-text-tertiary);
  text-align: left;
}
/* Mobile-only .cs-footer padding override removed — Figma binds all 4 sides to
   Padding/Section uniformly, no special sm-breakpoint value; the base rule above
   already resolves to --padding-section's own 16px at this width. */


/* ─── SCROLL TO TOP (Figma 831:106923) ───────────────────────────────────────
   Moved here from case-study.css — used by every case-study-*.php template and
   about.php now, not case-study-specific. Same text+icon pattern as .btn-tertiary
   / .cs-hero__jumps a, but the chevron leads the text (Figma: icon before "Top",
   not after) and it's a fixed-position floating control instead of an inline link.
   Figma placed it flush to the mockup's viewport corner (0 margin) — that's an
   artifact of the 600×800 thumbnail frame, not a real spec, so it's offset here
   using --padding-section like the rest of the site's edge margins (nav, footer).
   Visibility/scroll-direction logic: functions.php (ampm_scroll_top_js) — trigger
   point is #context on case-study pages, one viewport height as a generic fallback
   on pages without it (about.php). Background: Figma added a GLASS effect (radius
   58) to this component — reusing the same glass recipe already built for
   nav.am-nav's OnScroll state (blur(55px)) rather than a separate one-off value,
   per user instruction. Padding: Figma's "Button Base" binds both left and right to
   Padding/Button Horizontal Padding (--padding-button-horizontal) — code initially
   only used it on the right (icon-leading asymmetry from the base Tertiary
   component), fixed to match both sides per Figma update. Radius 54px lives on the
   outer "Property 1=Scroll" wrapper in Figma (literal, not a bound variable), not
   on Button Base itself. */
.cs-scroll-top {
  position: fixed;
  right: var(--padding-section);
  bottom: var(--padding-section);
  z-index: 9990;
  display: inline-flex;
  align-items: center;
  gap: var(--size-4);
  padding: 8px var(--padding-button-horizontal);
  border-radius: 54px;
  background: rgba(0, 0, 0, 0.004);
  backdrop-filter: blur(55px);
  -webkit-backdrop-filter: blur(55px);
  border: none;
  font-family: var(--button-font-family);
  font-size: 14px;
  font-weight: var(--button-font-weight);
  color: var(--color-action-secondary-text);
  text-decoration: none;
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, color 0.2s ease;
}
.cs-scroll-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
/* Figma's Glass effect has a Light angle of -45° (upper-left), which renders as a
   bright rim on the upper-left edge and a dimmer-but-still-visible rim on the
   lower-right — backdrop-filter alone can't reproduce that directional highlight,
   so it's faked with a 1px gradient-border ring (padding-box/mask-exclude trick)
   running the same -45°→135° diagonal. Both ends use the same rim color (only
   opacity differs), built via color-mix from --color-action-secondary-text — the
   same token that colors the button's own text/icon — rather than a hardcoded
   white/black, so it (a) matches the button visually and (b) still adapts to
   light/dark mode automatically since that token itself is mode-aware. */
.cs-scroll-top::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--color-action-secondary-text) 55%, transparent) 0%, transparent 35%, transparent 65%, color-mix(in srgb, var(--color-action-secondary-text) 25%, transparent) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}
.cs-scroll-top::before {
  content: '';
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M15 12.5L10 7.5L5 12.5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M15 12.5L10 7.5L5 12.5' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E") no-repeat center / contain;
  flex-shrink: 0;
}
.cs-scroll-top:hover { color: var(--color-action-secondary-hover); }


/* ─── Bento grid system ──────────────────────────────────────────────────── */
/*
 * NEW — added alongside bento card component.
 * Grid tokens live here (not tokens.css) because they are layout-level
 * concerns specific to the bento component, not global design primitives.
 */
:root {
  /* Grid configuration */
  --bento-cols:       12;
  --bento-gap:        var(--size-12);   /* 12px column + row gap */
  --bento-margin:     var(--size-32);   /* 32px outer margin */
  --bento-max:        1440px;           /* max container width */

  /* Card size: column spans at 12-col baseline */
  --card-span-s:      3;   /* stats, single metrics, tag clusters */
  --card-span-m:      6;   /* case study previews, philosophy items */
  --card-span-l:      9;   /* featured work, hero panel */
  /* Full = grid-column: 1 / -1  (not a span value, used directly) */

  /* Card min/max widths — guardrails independent of grid math */
  --card-s-min:       200px;
  --card-s-max:       360px;
  --card-m-min:       320px;
  --card-m-max:       680px;
  --card-l-min:       480px;
  --card-l-max:      1020px;

  /* Card anatomy slot dimensions */
  --card-header-h:    52px;   /* heading row fixed height */
  --card-thumb-size:  36px;   /* thumbnail in heading row */
  --card-image-h-s:  140px;   /* image placeholder — small card */
  --card-image-h-m:  220px;   /* image placeholder — medium card */
  --card-image-h-l:  320px;   /* image placeholder — large card */

  /* Card internal padding (overrides existing --card-padding-* aliases) */
  --card-pad-s:       var(--size-16);  /* 16px — small card */
  --card-pad-m:       var(--size-24);  /* 24px — medium card */
  --card-pad-l:       var(--size-32);  /* 32px — large card */
}


/* ─── Bento container ────────────────────────────────────────────────────── */
.bento-wrap {
  max-width: var(--bento-max);
  margin-inline: auto;
  padding-inline: var(--bento-margin);
}

.bento {
  display: grid;
  grid-template-columns: repeat(var(--bento-cols), 1fr);
  gap: var(--bento-gap);
  align-items: start;
}

/* Responsive column counts */
@media (max-width: 1439px) { .bento { grid-template-columns: repeat(8, 1fr); } }
@media (max-width:  767px) { .bento { grid-template-columns: repeat(4, 1fr); } }
@media (max-width:  479px) { .bento { grid-template-columns: repeat(2, 1fr); } }


/* ─── Bento card — base ──────────────────────────────────────────────────── */
/*
 * Composable: .card + .card--{size} + .card--{theme}
 * e.g. <div class="card card--m card--inverse">
 * Internal sizing driven by scoped custom properties (--_pad, --_image-h).
 */
.card {
  --_pad:     var(--card-pad-m);
  --_image-h: var(--card-image-h-m);

  background:    var(--color-surface-primary);
  border:        var(--border-width-thin) solid var(--color-border-subtle);
  border-radius: var(--card-radius);
  box-shadow:    var(--shadow-sm);
  overflow:      hidden;
  display:       flex;
  flex-direction: column;
  min-width:     0;
  transition:
    transform  220ms cubic-bezier(0.16,1,0.3,1),
    box-shadow 220ms cubic-bezier(0.16,1,0.3,1);
}

.card:hover {
  transform:  translateY(-2px);
  box-shadow: var(--shadow-md);
}


/* ─── Card size modifiers ────────────────────────────────────────────────── */
.card--s {
  --_pad:     var(--card-pad-s);
  --_image-h: var(--card-image-h-s);
  grid-column: span var(--card-span-s);
  min-width:   var(--card-s-min);
  max-width:   var(--card-s-max);
}

.card--m {
  --_pad:     var(--card-pad-m);
  --_image-h: var(--card-image-h-m);
  grid-column: span var(--card-span-m);
  min-width:   var(--card-m-min);
  max-width:   var(--card-m-max);
}

.card--l {
  --_pad:     var(--card-pad-l);
  --_image-h: var(--card-image-h-l);
  grid-column: span var(--card-span-l);
  min-width:   var(--card-l-min);
  max-width:   var(--card-l-max);
}

.card--full {
  --_pad:     var(--card-pad-l);
  --_image-h: 400px;
  grid-column: 1 / -1;
}

/* Responsive span overrides */
@media (max-width: 1439px) {
  .card--s    { grid-column: span 4; max-width: 100%; }
  .card--m    { grid-column: span 4; max-width: 100%; }
  .card--l    { grid-column: span 8; max-width: 100%; }
}
@media (max-width: 767px) {
  .card--s    { grid-column: span 4; min-width: 0; max-width: 100%; }
  .card--m    { grid-column: span 4; min-width: 0; max-width: 100%; }
  .card--l    { grid-column: span 4; min-width: 0; max-width: 100%;
                --_image-h: var(--card-image-h-m); }
}
@media (max-width: 479px) {
  .card--s,
  .card--m,
  .card--l    { grid-column: span 2; --_image-h: var(--card-image-h-s); }
}


/* ─── Card theme modifiers ───────────────────────────────────────────────── */
.card--inverse {
  background:  var(--color-surface-inverse);
  border-color: transparent;
}

.card--accent {
  background:  var(--color-accent);
  border-color: var(--color-accent);
}

.card--tint {
  background:  var(--color-accent-subtle);
  border-color: rgba(212,79,46,0.2);
}

.card--inset {
  background:  var(--color-surface-tertiary);
  border-color: var(--color-border-subtle);
}


/* ─── Card slots ─────────────────────────────────────────────────────────── */

/* Slot 01 — card__header */
.card__header {
  display:    flex;
  align-items: center;
  gap:        var(--size-12);
  padding:    var(--_pad) var(--_pad) 0;
  min-height: var(--card-header-h);
  flex-shrink: 0;
}

.card__header-thumb {
  width:        var(--card-thumb-size);
  height:       var(--card-thumb-size);
  border-radius: var(--radius-md);
  background:   var(--color-surface-tertiary);
  border:       var(--border-width-thin) solid var(--color-border-subtle);
  flex-shrink:  0;
  overflow:     hidden;
}

.card__header-thumb img {
  width: 100%; height: 100%; object-fit: cover;
}

.card__header-meta { flex: 1; min-width: 0; }

.card__header-tags {
  display:    flex;
  flex-wrap:  nowrap;
  gap:        var(--size-4);
  flex-shrink: 0;
  overflow:   hidden;
}

.card__header-action {
  flex-shrink:   0;
  font-family:   var(--font-mono);
  font-size:     10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  padding:       var(--size-2) var(--size-12);
  border:        var(--border-width-default) solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  background:    transparent;
  color:         var(--color-text-secondary);
  cursor:        pointer;
  white-space:   nowrap;
  text-decoration: none;
  display:       inline-flex;
  align-items:   center;
  gap:           var(--size-4);
  transition:    background 150ms, border-color 150ms, color 150ms;
}

.card__header-action:hover {
  background:   var(--color-text-primary);
  border-color: var(--color-text-primary);
  color:        var(--color-text-on-accent);
}

/* Slot 02 — card__image */
.card__image {
  width:        100%;
  height:       var(--_image-h);
  background:   var(--color-surface-tertiary);
  flex-shrink:  0;
  overflow:     hidden;
  position:     relative;
}

.card__header + .card__image { margin-top: var(--size-8); }
.card > .card__image:first-child { border-radius: var(--card-radius) var(--card-radius) 0 0; }

.card__image img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Slot 03 — card__body */
.card__body {
  padding:       var(--_pad);
  display:       flex;
  flex-direction: column;
  gap:           var(--size-4);
  flex:          1;
}

.card__image + .card__body { padding-top: var(--_pad); }

.card__title {
  font-family:   var(--font-display);
  font-size:     var(--text-h3-size);
  font-weight:   var(--text-h3-weight);
  line-height:   var(--leading-snug);
  letter-spacing: var(--tracking-snug);
  color:         var(--color-text-primary);
}

.card--s .card__title  { font-size: var(--size-20); }
.card--m .card__title  { font-size: var(--size-24); }
.card--l .card__title  { font-size: var(--size-32); }
.card--full .card__title { font-size: var(--size-40); }

.card__description {
  font-size:   var(--size-12);
  font-weight: var(--weight-300);
  line-height: var(--leading-relaxed);
  color:       var(--color-text-secondary);
}

.card--l .card__description,
.card--full .card__description { font-size: var(--size-16); }

/* Slot 04 — card__data */
.card__data {
  padding:     var(--_pad);
  padding-top: 0;
  display:     flex;
  gap:         var(--size-24);
  align-items: flex-end;
  border-top:  var(--border-width-thin) solid var(--color-border-subtle);
  margin-top:  auto;
  padding-top: var(--size-16);
}

.card > .card__data { padding: var(--_pad); }

.card__metric { display: flex; flex-direction: column; gap: 2px; }

.card__metric-value {
  font-family:   var(--font-display);
  font-size:     var(--size-32);
  font-style:    italic;
  line-height:   1;
  letter-spacing: var(--tracking-tight);
  color:         var(--color-text-primary);
}

.card--s .card__metric-value { font-size: var(--size-24); }

.card__metric-label {
  font-family:   var(--font-mono);
  font-size:     10px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color:         var(--color-text-tertiary);
}


/* ─── Card theme: color overrides for slots ──────────────────────────────── */
.card--inverse .card__title,
.card--inverse .card__metric-value   { color: var(--color-text-inverse); }
.card--inverse .card__description    { color: rgba(245,243,238,0.55); }
.card--inverse .card__metric-label   { color: rgba(245,243,238,0.35); }
.card--inverse .card__data           { border-color: rgba(245,243,238,0.1); }
.card--inverse .card__header-action  { border-color: rgba(245,243,238,0.25); color: rgba(245,243,238,0.7); }

.card--accent .card__title           { color: var(--color-text-on-accent); }
.card--accent .card__description     { color: rgba(255,255,255,0.75); }
.card--accent .card__metric-value    { color: var(--color-text-on-accent); }
.card--accent .card__metric-label    { color: rgba(255,255,255,0.5); }
.card--accent .card__data            { border-color: rgba(255,255,255,0.2); }

.card--tint .card__title             { color: var(--color-accent-text); }
.card--tint .card__metric-value      { color: var(--color-accent); }
.card--tint .card__data              { border-color: var(--color-accent-subtle); }


/* ─── Animations ─────────────────────────────────────────────────────────── */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}


/* ─── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    padding: 48px 20px 40px;
  }

  section,
  .wp-block-group {
    padding: var(--space-section) 20px;
  }

  .pillars-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .about-grid,
  .contact-grid {
    grid-template-columns: 1fr;
  }

  .case-card {
    grid-template-columns: 60px 1fr;
  }

  .case-preview,
  .case-meta {
    display: none;
  }

  .process-steps {
    grid-template-columns: repeat(3, 1fr);
  }

  .figma-controls {
    grid-template-columns: 1fr;
  }

  footer,
  .site-footer {
    flex-direction: column;
    gap: 12px;
    text-align: center;
  }
}

@media (max-width: 480px) {
  .process-steps {
    grid-template-columns: repeat(2, 1fr);
  }

  .pillars-grid {
    grid-template-columns: 1fr;
  }

  .hero-stats {
    grid-template-columns: repeat(3, 1fr);
  }
}


/* ─── Base Module ─────────────────────────────────────────────────────────── */
/* BaseModule=Default Right — Figma node 45:5                                 */
/* Body: grid — Content (min 300, max 600) | Image (min 200, FILL)            */
/* Image container clips content (Figma clipsContent:true) → bleed from right */
.bm-body {
  display: grid;
  grid-template-columns: minmax(300px, 600px) minmax(200px, 1fr);
}

.bm-content {
  min-width: 300px;
  max-width: 600px;
}

.bm-media {
  min-width: 200px;
  height: var(--img-hero-height);
  display: flex;
  align-items: center;
  justify-content: flex-start;
  overflow: hidden;
}

/* Height fills container; width auto-adjusts to preserve aspect ratio (bleeds right, clipped by overflow:hidden) */
/* max-width: none overrides parent theme's global img { max-width: 100% } reset */
.bm-media img {
  height: 100%;
  width: auto;
  max-width: none;
  flex-shrink: 0;
  display: block;
}

/* ≤530px: image column wraps below text — single-column layout */
/* Image retains width:752px + overflow:hidden clip; bleed behavior unchanged */
@media (max-width: 530px) {
  .bm-body {
    grid-template-columns: 1fr;
  }
}


/* ─── BaseModule > Opportunities ─────────────────────────────────────────── */
/* Figma node 491:3446 — Pain Points section component                        */
/* Section background/gap updated 2026-09-25 per Figma (484:2808): background
   was Surface/Tertiary (mint), now Surface/Page — confirmed via the live bound
   fill variable, not the Surface/Primary originally described (different token,
   different hex value — flag if Primary was actually intended). Gap between
   content (.cs-pp cards) removed — Figma's itemSpacing on this frame is a
   literal, unbound 0. */
.cs-painpoints {
  background: var(--color-surface-page);
  padding: var(--padding-section) 0;
  overflow: hidden;
}
.cs-painpoints__inner {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.cs-painpoints__heading {
  font-family: var(--font-standard);
  font-size: var(--text-h1-size);
  font-weight: var(--weight-600);
  color: var(--color-text-primary);
  padding: var(--size-8) var(--padding-section) var(--size-8);
  position: relative;
  z-index: 1;
}

/* Each pain point card — updated 2026-09-25 per Figma (491:3446, BaseModule=
   Opportunity): fill was Surface/Tertiary, user changed it to Surface/Page in
   Figma (confirmed via the live bound fill variable) to match the section's own
   background now that .cs-painpoints uses Surface/Page too. */
.cs-pp {
  background: var(--color-surface-page);
  border-radius: var(--size-8);
  padding: var(--padding-section);
  position: relative;
}
/* All direct children sit above the ::before decorative shape */
.cs-pp > * { position: relative; z-index: 1; }
/* Decorative rotated square — bleeds above card top into mint section */
/* Matches Figma node 555:22917 — wrapper left:-391px top:-79px size:832.972px (589*√2) */
.cs-pp::before {
  content: '';
  position: absolute;
  width: 589px;
  height: 589px;
  border-radius: 64px;
  background: linear-gradient(160deg, var(--color-accent-tertiary) 40%, var(--color-accent-secondary) 70%);
  left: -269px;
  top: 43px;
  transform: rotate(45deg);
  pointer-events: none;
  z-index: 0;
}

/* Question headline */
.cs-pp__question {
  font-family: var(--text-h3-family);
  font-size: var(--text-h3-size);
  font-weight: var(--text-h3-weight);
  color: var(--color-text-primary);
  line-height: var(--leading-normal);
  margin-bottom: var(--size-8);
}

/* Description body */
.cs-pp__body {
  font-family: var(--text-body-lg-family);
  font-size: var(--text-body-lg-size);
  font-weight: var(--text-body-lg-weight);
  line-height: var(--text-body-lg-leading);
  color: var(--color-text-tertiary);
  margin-bottom: var(--size-24);
}

/* Main: wraps Customer POV + HMW — no horizontal padding (Figma 525:4078) */
.cs-pp__main {
  display: flex;
  flex-direction: column;
  gap: var(--size-32);
  width: 100%;
}

/* Customer POV */
.cs-pov__label {
  display: block;
  font-family: var(--text-h4-family);
  font-size: var(--text-h4-size);
  font-weight: var(--text-h4-weight);
  color: var(--color-text-primary);
  margin-bottom: var(--size-16);
  max-width: 1000px;
}
.cs-pov__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--size-4);
  align-items: flex-start;
  padding: var(--size-8) 0;
}
.cs-pov__col {
  display: flex;
  flex-direction: column;
  flex: 1 0 0;
  gap: var(--size-8);
  min-width: 164px;
  padding: var(--size-8) var(--size-12);
}
.cs-pov__col-title {
  display: flex;
  align-items: center;
  gap: var(--size-8);
  width: 100%;
}
.cs-pov__icon {
  width: var(--size-20);
  height: var(--size-20);
  flex-shrink: 0;
  color: var(--color-text-primary);
}
.cs-pov__col .cs-label {
  font-family: var(--font-standard);
  font-size: var(--text-body-default-size);
  font-weight: var(--text-body-default-weight);
  color: var(--color-text-primary);
  margin-bottom: 0;
}
.cs-pov__col p {
  font-family: var(--text-body-lg-family);
  font-size: var(--text-body-lg-size);
  font-weight: var(--text-body-lg-weight);
  line-height: var(--text-body-lg-leading);
  color: var(--color-text-tertiary);
}

/* HMW callout: off-white card with 1px teal-to-blue gradient border
   (Figma 525:4695: strokeWeight 1, gradient Color/Accent/Secondary → Color/Accent/Tertiary) */
.cs-hmw {
  display: flex;
  flex-direction: column;
  gap: var(--space-list-gap);
  border: 1px solid transparent;
  border-radius: var(--size-8);
  padding: var(--padding-section);
  background:
    linear-gradient(var(--color-surface-primary), var(--color-surface-primary)) padding-box,
    linear-gradient(135deg, var(--color-accent-secondary), var(--color-accent-tertiary)) border-box;
}
.cs-hmw p {
  font-family: var(--text-h4-family);
  font-size: var(--text-h4-size);
  font-weight: var(--text-h4-weight);
  color: var(--color-text-primary);
  line-height: var(--text-h4-leading);
}

/* Key Considerations: flex-wrap 3-column evidence grid */
.cs-considerations {
  display: flex;
  flex-direction: column;
  gap: var(--padding-section);
}
.cs-evidence-groups {
  display: flex;
  flex-wrap: wrap;
  row-gap: var(--space-section-large);
  column-gap: var(--space-list-gap);
  align-items: flex-start;
}
.cs-considerations__label {
  display: block;
  font-family: var(--text-subheading-family);
  font-size: var(--text-subheading-size);
  font-weight: var(--text-subheading-weight);
  line-height: var(--text-subheading-leading);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}
.cs-consideration {
  flex: 1 0 0;
  min-width: var(--layout-evidence-col-min);
  max-width: var(--layout-evidence-col-max);
  display: flex;
  flex-direction: column;
  gap: var(--padding-container-vertical-2);
  padding: var(--size-4) 0;
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}
.cs-consideration:last-child { border-bottom: none; padding-bottom: 0; }
.cs-consideration__title {
  font-family: var(--text-h5-family);
  font-size: var(--text-h5-size);
  font-weight: var(--text-h5-weight);
  color: var(--color-text-primary);
  margin-bottom: 0;
}
/* Image: beige padded frame matching Figma bg-[#f2f0eb] p-[12px] */
.cs-consideration__img {
  display: block;
  width: 100%;
  border-radius: var(--size-8);
  background: #f2f0eb;
  padding: var(--size-12);
  box-sizing: border-box;
  border: none;
  margin-bottom: 0;
}
/* Tags: solid teal pill, inverse text */
.cs-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--size-4);
  margin-bottom: 0;
}
.cs-tag {
  font-family: var(--text-body-small-family);
  font-size: var(--text-body-small-size);
  font-weight: var(--text-body-small-weight);
  line-height: var(--text-body-small-leading);
  color: var(--color-text-tertiary);
  background: var(--color-accent-tertiary);
  border: none;
  border-radius: var(--size-4);
  padding: var(--size-4) var(--size-8);
}
.cs-consideration p {
  font-family: var(--text-body-lg-family);
  font-size: var(--text-body-lg-size);
  font-weight: var(--text-body-lg-weight);
  line-height: var(--text-body-lg-leading);
  color: var(--color-text-tertiary);
}

@media (max-width: 767px) {
  .cs-pov__grid { flex-direction: column; }
}


/* ─── BaseModule > FinalFinal / Final ────────────────────────────────────── */
/* Figma nodes 596:11855 (FinalFinalMod), 593:5157 (BaseModule>FinalFinal),   */
/* 594:10430 (BaseModule>Final) — card used in case-study.php's masonry grid  */
/* (.cs-bringing__masonry / __col in case-study.css). FinalFinalMod>Default   */
/* is now 5 flat flex children: Col1[pair], bare card, Col3[wide pair],       */
/* bare card, Col5[pair] — bare cards use the same min/max as any other item. */
/* Card structure mirrors Figma: Card Container > IMG Container, Content     */
/* Container. Figma pins these frames to the Light variable mode (tagged     */
/* [Light] in the layers panel), so Color/Surface/Primary + Color/Text/      */
/* Primary must resolve to their light values here always — override the    */
/* semantic tokens locally rather than using them as-is, since they flip    */
/* under prefers-color-scheme: dark at the :root level. */
.cs-bringing__item {
  --color-surface-primary: #ffffff;
  --color-text-primary: #0f0b12;
  background: var(--color-surface-primary);
  border-radius: var(--size-8);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: var(--img-bento-col-min);
  max-width: var(--img-bento-col-max);
  min-height: var(--img-bento-card-min-height);
}
.cs-bringing__item--wide {
  min-width: var(--img-bento-wide-img-min-width);
  max-width: var(--img-bento-wide-img-max-width);
  width: 100%;
}
/* Default (FinalFinal): image instance is HUG width / FILL height in Figma —
   it keeps its natural aspect ratio and is centered, not stretched edge-to-edge. */
.cs-bringing__item__img {
  display: flex;
  justify-content: center;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.cs-bringing__item__img img {
  display: block;
  width: auto;
  max-width: 100%;
  height: 100%;
  min-height: 150px;
  object-fit: cover;
  object-position: top;
  margin: 0 auto;
}
/* Wide (Final): the IMGPWMD container itself (not the image) is Fill/Fill with its own
   Figma-bound min/max-width + max-height — the image inside still uses the same
   height-fill / width-auto (aspect-locked) pattern as the default card above. */
.cs-bringing__item--wide .cs-bringing__item__img {
  min-width: var(--img-bento-wide-img-min-width);
  max-width: var(--img-bento-wide-img-max-width);
  max-height: var(--img-bento-wide-img-max-height);
}
/* Instance-specific: "Responsive" card only (FinalFinalMod>Default > Col 3, Instance 1) —
   left-align the image crop instead of centering it, sm tier only. Figma sets this via
   counterAxisAlignItems on IMG/IMGPWMD; reverts to the default centered crop at lg+
   (comment corrected 2026-09-25, was "md+" — the 1024px threshold itself was already
   correct, it's lg's real min-width, not md's/600px; see tokens.css's responsive-
   breakpoint-thresholds fix). The image's own max-width:100% always fills the container,
   so there's no flex free space for justify-content/margin to act on — the crop position
   is controlled by object-position instead (object-fit:cover is what's actually doing
   the cropping). */
.cs-bringing__item__img--align-left-sm img {
  object-position: left top;
}
@media (min-width: 1024px) {
  .cs-bringing__item__img--align-left-sm img {
    object-position: top;
  }
}
.cs-bringing__item__content {
  flex: 0 0 auto;
  background: var(--color-surface-primary);
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  padding: 0 var(--size-8) var(--size-8);
}
.cs-bringing__item__content h4 {
  font-family: var(--font-standard);
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-700);
  color: var(--color-text-primary);
  padding: var(--size-8) 0 var(--size-4);
}
.cs-bringing__item__content p {
  font-size: var(--text-body-small-size);
  font-weight: var(--weight-300);
  line-height: var(--leading-tight);
  color: var(--color-text-primary);
}


/* ─── PASSWORD GATE (Figma: BaseModule=ModalPW, 1061:122676) ─────────────────
   Shell behind the modal (nav + minimal placeholder, rendered by
   ampm_maybe_show_password_gate() in functions.php via the template_redirect
   hook) + the modal itself. Responsive per the user's explicit spec: centered
   with a backdrop at lg+ (≥1024px), top-aligned/full-screen below that. */
.pw-shell {
  min-height: 60vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--nav-height) + var(--size-32)) var(--padding-section) var(--size-32);
  text-align: center;
}
.pw-shell__text {
  font-family: var(--font-standard);
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-300);
  color: var(--color-text-secondary);
  margin-bottom: var(--size-16);
}

.pw-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 20000;
  display: none;
}
.pw-modal-overlay.is-open {
  display: flex;
}
.pw-modal {
  /* Color/Surface/Secondary — distinct from the input fields' Surface/Primary
     fill, per the user's updated Figma (1061:122676). */
  background: var(--color-surface-secondary);
  width: 100%;
  display: flex;
  flex-direction: column;
}
/* sm/md (<1024px): full-screen, top-aligned — the modal IS the screen, no
   backdrop needed. */
.pw-modal-overlay {
  align-items: flex-start;
  justify-content: stretch;
}
.pw-modal {
  height: 100dvh;
  overflow-y: auto;
  border-radius: 0;
}
/* lg+ (≥1024px): centered with a backdrop, contained width — not Figma's literal
   341px component width (sized for its component-frame context, not a real
   browser modal); sized against the form's own real content instead. */
@media (min-width: 1024px) {
  .pw-modal-overlay {
    align-items: center;
    justify-content: center;
    /* Color/Surface/Primary at 90%, per the user's request — same color-mix
       pattern already used elsewhere on the site for adaptive light/dark overlay
       colors, rather than a flat hardcoded black. */
    background: color-mix(in srgb, var(--color-surface-primary) 90%, transparent);
    padding: var(--size-24);
  }
  .pw-modal {
    max-width: 440px;
    max-height: 90vh;
    /* Matches the real Figma instance's rendered height (1076:122804, 477px) —
       gives the Action Row's margin-top:auto (below) room to actually push the
       buttons to the bottom instead of the modal just hugging its content. */
    min-height: 477px;
    border-radius: var(--size-8);
    box-shadow: 0 24px 48px rgba(0, 0, 0, 0.25);
  }
}

.pw-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--size-16);
  flex-shrink: 0;
}
.pw-modal__title {
  font-family: var(--text-h4-family);
  font-size: var(--text-h4-size);
  font-weight: var(--text-h4-weight);
  color: var(--color-text-primary);
}
.pw-modal__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: none;
  color: var(--color-text-primary);
  cursor: pointer;
  flex-shrink: 0;
}
.pw-modal__close::before {
  content: '';
  display: block;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 5L15 15M15 5L5 15' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 5L15 15M15 5L5 15' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / contain;
}

.pw-modal__body {
  padding: 0 var(--size-16) var(--size-16);
  overflow-y: auto;
  /* Flex column so .pw-modal__actions' margin-top:auto can push the buttons to
     the bottom, filling whatever vertical space the rest of the form doesn't
     use — matches the Figma instance's large empty gap above the Action Row. */
  display: flex;
  flex-direction: column;
  flex: 1;
}
.pw-modal__form {
  /* Continues the flex-column chain from .pw-modal__body so .pw-modal__actions'
     margin-top:auto (below) reaches all the way up to consume the real extra
     space, not just hug its own content. */
  display: flex;
  flex-direction: column;
  flex: 1;
}
.pw-modal__desc {
  font-family: var(--font-standard);
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-200);
  line-height: var(--leading-normal);
  color: var(--color-text-primary);
  margin-bottom: var(--size-16);
}
/* Floating label: "Password*" sits centered inside the field as hint text
   (Color/Text/Tertiary) until the field is focused or filled, then floats to a
   small label above the value (Color/Text/Primary) — per the user's Figma
   update (1074:122731 "Regular inputs", Style=Field in). The label is a
   same-DOM sibling positioned absolutely over the input; requires the input's
   own placeholder=" " (functions.php) for :placeholder-shown to work. */
.pw-modal__field {
  position: relative;
  margin-bottom: var(--size-16);
}
.pw-modal__field input[type="password"] {
  width: 100%;
  background: var(--color-surface-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--size-4);
  /* Taller than Figma's literal 52px field, per the user's request — more
     top padding so the floated label (below) has real clearance above the
     typed text/cursor instead of crowding it. */
  padding: var(--size-24) var(--size-16) var(--size-12);
  font-family: var(--font-standard);
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-300);
  color: var(--color-text-primary);
  box-sizing: border-box;
}
.pw-modal__field label {
  position: absolute;
  left: var(--size-16);
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-standard);
  font-size: var(--text-body-default-size);
  font-weight: var(--weight-300);
  line-height: var(--leading-tight);
  color: var(--color-text-tertiary);
  pointer-events: none;
  transition: top 0.15s ease, font-size 0.15s ease, color 0.15s ease;
}
.pw-modal__field input[type="password"]:focus,
.pw-modal__field input[type="password"]:not(:placeholder-shown) {
  outline: none;
  border-color: var(--color-action-primary);
}
.pw-modal__field input[type="password"]:focus + label,
.pw-modal__field input[type="password"]:not(:placeholder-shown) + label {
  /* Was crowding the typed text against the floated label — the default
     body-text line-height (1.5) made the label's own line box much taller
     than its 12px glyphs, leaving almost no gap above the input padding.
     leading-tight (1.2) on the label rule above fixes that; top nudged up
     slightly too now that the field itself is taller. */
  top: var(--size-4);
  transform: none;
  font-size: var(--text-body-small-size);
  color: var(--color-text-primary);
}
.pw-modal__field--error input[type="password"] {
  border-color: var(--color-danger-strong);
}
.pw-modal__error {
  font-family: var(--font-standard);
  font-size: var(--text-body-small-size);
  font-weight: var(--weight-300);
  color: var(--color-danger-strong);
  margin: calc(-1 * var(--size-8)) 0 var(--size-16);
}
/* Widget itself stays full width (data-size="flexible" in functions.php).
   Wrapping box: Figma's real Captcha frame (1074:122789) has cornerRadius 0
   and an INSIDE-aligned 1px Color/Border/Subtle stroke — confirmed directly
   via the Plugin API, not guessed. box-sizing:border-box matches that INSIDE
   alignment (border doesn't add to the box's own width). It's now the last
   element, pushed to the bottom of the modal (margin-top: auto, against the
   flex-column chain started at .pw-modal__body) — Figma reflowed Action Row
   to sit right after the field instead. */
.cf-turnstile {
  width: 100%;
}
/* Cloudflare renders the actual widget inside an <iframe>; browsers apply a
   default border to iframes (Chrome/Firefox's UA stylesheet: 2px inset) that
   our CSS never touched. In dark mode this shows as a stray light/white
   rectangle around the widget's own (correctly dark-themed) content — not
   our .pw-modal__captcha border, which is confirmed correct via computed
   styles. Reset explicitly rather than relying on the widget to do it. */
.cf-turnstile iframe {
  border: none;
  display: block;
}
.pw-modal__captcha {
  box-sizing: border-box;
  border: 1px solid var(--color-border-subtle);
  border-radius: 0;
  padding: var(--size-16);
  margin-top: auto;
}

/* Actions now sits right after the field/error, top-aligned — no longer
   stretched or pushed down (that's .pw-modal__captcha's job now). Figma:
   1076:122804, Action Row moved to y=144, right after the field. No divider;
   Figma's Divider node is hidden in this version. */
.pw-modal__actions {
  display: flex;
  flex-direction: column;
  gap: var(--size-16);
}
.pw-modal__actions .btn-primary,
.pw-modal__actions .btn-tertiary {
  width: 100%;
  justify-content: center;
}

