/* /website-unlocked -- follows the site's normal light/dark theme system
   exactly like /the-practice (no forced theme, var(--paper)/var(--ink)
   throughout). What makes this page feel distinct: a real full-bleed hero
   photo (a standalone illustration Jason drew for this page -- a wavy
   rainbow field of keys and keyholes, not an Art Store piece) with the
   headline in a liquid-glass panel on top; one real vertical "build"
   sequence (.wu-story) instead of a separate timeline + tile grid that
   repeated the same project list twice, with icons copied from the
   homepage's own #projects treatment (.project-icon-* in styles.css)
   minus their border; and liquid-glass panels using the site's real
   Golden Gate recipe (.nav-glass/.practice-glass-panel). The hero
   artwork's own bold palette (sampled directly from the file, see
   --wu-c1..6 below) carries through as accent color on the story-card
   tints and timeline dots -- the one place this page goes full color
   instead of the site's usual muted tones. The receipt is the one
   deliberate exception: a retro dot-matrix register receipt, no glass
   frame around it, styled like a real photographed object in both
   themes. */

:root {
  --wu-c1: 0, 173, 255; /* sky blue */
  --wu-c2: 161, 62, 161; /* purple */
  --wu-c3: 255, 222, 0; /* yellow */
  --wu-c4: 255, 0, 131; /* pink */
  --wu-c5: 136, 191, 0; /* green */
  --wu-c6: 255, 109, 0; /* orange */
}

.wu-wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: clamp(100px, 14vh, 140px) clamp(20px, 6vw, 88px) 100px;
  position: relative;
  z-index: 1;
}

/* ---- shared glass-panel recipe, the real Golden Gate depth tokens --
   base rule uses the "on-light" pair; the dark override below swaps in
   the "on-dark" pair, same two-rule pattern every other glass component
   on the site uses (see .nav-glass/.practice-glass-panel). ---- */
.wu-glass {
  border: 1px solid var(--glass-stroke);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)),
    var(--glass-fill);
  backdrop-filter: blur(36px) saturate(2.2) contrast(1.1);
  -webkit-backdrop-filter: blur(36px) saturate(2.2) contrast(1.1);
  box-shadow:
    0 14px 38px var(--glass-shadow),
    inset 0 1px 0 var(--glass-depth-highlight-on-light),
    inset 0 0 16px rgba(255, 255, 255, 0.16),
    inset 0 -1px 0 var(--glass-depth-edge-on-light);
}
:root[data-theme="dark"] .wu-glass {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent),
    var(--glass-fill);
  box-shadow:
    0 14px 38px var(--glass-shadow),
    inset 0 1px 0 var(--glass-depth-highlight-on-dark),
    inset 0 -1px 0 var(--glass-depth-edge-on-dark);
}
/* Story cards specifically: a faded color wash cycling through the hero
   artwork's real sampled palette (--wu-c1..6), layered under the same
   glass recipe above -- more liquid-glass, not just frosted grey. */
.wu-story-card.wu-glass {
  background:
    linear-gradient(145deg, rgba(var(--wu-c1), 0.16), transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)),
    var(--glass-fill);
}
.wu-story-item:nth-of-type(6n+2) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c2), 0.16), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)), var(--glass-fill); }
.wu-story-item:nth-of-type(6n+3) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c3), 0.18), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)), var(--glass-fill); }
.wu-story-item:nth-of-type(6n+4) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c4), 0.16), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)), var(--glass-fill); }
.wu-story-item:nth-of-type(6n+5) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c5), 0.16), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)), var(--glass-fill); }
.wu-story-item:nth-of-type(6n) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c6), 0.18), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.48), rgba(255, 255, 255, 0.1) 55%, rgba(255, 255, 255, 0.02)), var(--glass-fill); }
:root[data-theme="dark"] .wu-story-card.wu-glass {
  background:
    linear-gradient(145deg, rgba(var(--wu-c1), 0.2), transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent),
    var(--glass-fill);
}
:root[data-theme="dark"] .wu-story-item:nth-of-type(6n+2) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c2), 0.22), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent), var(--glass-fill); }
:root[data-theme="dark"] .wu-story-item:nth-of-type(6n+3) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c3), 0.2), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent), var(--glass-fill); }
:root[data-theme="dark"] .wu-story-item:nth-of-type(6n+4) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c4), 0.22), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent), var(--glass-fill); }
:root[data-theme="dark"] .wu-story-item:nth-of-type(6n+5) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c5), 0.2), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent), var(--glass-fill); }
:root[data-theme="dark"] .wu-story-item:nth-of-type(6n) .wu-story-card.wu-glass { background: linear-gradient(145deg, rgba(var(--wu-c6), 0.22), transparent 60%), linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02) 48%, transparent), var(--glass-fill); }

/* ---- hero: a real full-bleed photo band (same move The Practice/the
   homepage make for their own heroes) -- a standalone illustration Jason
   drew specifically for this page (not an Art Store piece, so no credit
   link), full-bleed behind everything, with the headline sitting in a
   real liquid-glass panel on top (.wu-glass -- same Golden Gate blur/
   saturate/contrast recipe every other panel on this page uses, just
   large enough to read as the hero's own focal card). The artwork's own
   bold palette (sampled directly from assets/website-unlocked-hero.png)
   becomes this page's accent colors from here down -- the one deliberate
   place this page goes full color instead of muted. ---- */
.wu-hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(420px, 56vh, 560px);
  padding: clamp(120px, 16vh, 160px) clamp(20px, 6vw, 88px) clamp(56px, 8vh, 84px);
  overflow: hidden;
  isolation: isolate;
}
.wu-hero-art {
  position: absolute;
  inset: 0;
  z-index: -1;
}
.wu-hero-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
}
.wu-hero-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(10, 9, 8, 0.4) 0%, rgba(10, 9, 8, 0.14) 44%, rgba(10, 9, 8, 0.05) 100%);
}
:root[data-theme="dark"] .wu-hero-art::after {
  background: linear-gradient(100deg, rgba(5, 4, 4, 0.56) 0%, rgba(5, 4, 4, 0.26) 44%, rgba(5, 4, 4, 0.1) 100%);
}
.wu-hero-panel {
  position: relative;
  z-index: 1;
  max-width: 560px;
  padding: 34px 36px;
  border-radius: 28px;
}
.wu-hero h1 {
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(2.6rem, 6.5vw, 4.4rem);
  line-height: 1.04;
  text-transform: uppercase;
  margin: 0 0 16px;
  text-wrap: balance;
  color: var(--ink);
}
.wu-opening {
  margin: 0;
  color: var(--muted);
  font-size: 1.08rem;
  line-height: 1.65;
}
@media (max-width: 860px) {
  .wu-hero {
    align-items: flex-end;
    min-height: clamp(380px, 68vh, 520px);
  }
  .wu-hero-panel {
    max-width: 100%;
    padding: 26px 24px;
  }
}
/* ---- section openers: eyebrow-weight h2 + a one-line sub, same beat
   every section repeats so "Timeline" / "Behind the scenes" / "The cost"
   / "Stack" each read as a real chapter start, not a bare label. ---- */
.wu-section-head {
  max-width: 640px;
  margin: 0 0 28px;
}
.wu-section-sub {
  margin: 8px 0 0;
  font-size: 0.95rem;
  color: var(--muted);
  line-height: 1.5;
}

#timeline {
  margin-bottom: 60px;
  scroll-margin-top: 70px;
}
#cost {
  scroll-margin-top: 70px;
}
/* .wu-cost sits outside .wu-wrap now (its own full-bleed band), so this
   has to cover both -- a plain ".wu-wrap h2" selector was silently
   missing the cost section's heading, leaving it at the browser's
   unstyled default h2 size. */
.wu-wrap h2,
.wu-cost h2 {
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(1.7rem, 3.4vw, 2.3rem);
  line-height: 1.12;
  text-transform: uppercase;
  margin: 0;
  text-wrap: balance;
  color: var(--ink);
}

/* ---- the build: one real vertical sequence (was two separate,
   repetitive sections -- a date-only timeline, then a tile grid covering
   almost the same projects again). Each entry pairs the date/title with
   its own "what's actually running it" detail in one place, down the
   page, normal scroll -- a left rail with a dot per entry connects them. ---- */
.wu-story {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.wu-story-item {
  display: flex;
  gap: 18px;
}
/* Build-in as each entry scrolls into view -- see website-unlocked.js.
   --d is a per-item stagger delay set inline. */
.wu-story-item.wu-rv {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 620ms cubic-bezier(0.16, 1, 0.3, 1), transform 620ms cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--d, 0ms);
}
.wu-story-item.wu-rv.is-in {
  opacity: 1;
  transform: none;
}
.wu-story-rail {
  flex: none;
  width: 16px;
  display: flex;
  justify-content: center;
  position: relative;
}
.wu-story-rail::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: -26px;
  width: 2px;
  background: var(--glass-stroke);
}
.wu-story-item:last-child .wu-story-rail::before {
  display: none;
}
/* Dots cycle through the same hero-sampled palette as the story-card
   tints beside them, same 6-step order, so each entry's dot matches its
   own card's color wash. */
.wu-story-dot {
  position: relative;
  z-index: 1;
  margin-top: 26px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: rgb(var(--wu-c1));
  box-shadow: 0 0 0 3px var(--paper);
}
.wu-story-item:nth-of-type(6n+2) .wu-story-dot { background: rgb(var(--wu-c2)); }
.wu-story-item:nth-of-type(6n+3) .wu-story-dot { background: rgb(var(--wu-c3)); }
.wu-story-item:nth-of-type(6n+4) .wu-story-dot { background: rgb(var(--wu-c4)); }
.wu-story-item:nth-of-type(6n+5) .wu-story-dot { background: rgb(var(--wu-c5)); }
.wu-story-item:nth-of-type(6n) .wu-story-dot { background: rgb(var(--wu-c6)); }
.wu-story-card {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: 18px;
  margin-bottom: 22px;
  padding: 22px;
  border-radius: 20px;
}
@media (max-width: 640px) {
  .wu-story-card {
    flex-direction: column;
  }
}
/* ---- icons: the exact homepage #projects treatment (size, rounded
   tile, per-project background color, invert filter for the Human
   Design key glyph) copied from .project-icon/.project-icon-* in
   styles.css -- just without the 1px border those have. "neutral" is
   the honest exception for Admin Portal/Schedule a Chat, which have no
   real public icon anywhere, so they get a plain muted tile instead of
   a brand-colored one that would misleadingly look official. ---- */
.wu-story-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 15px;
  overflow: hidden;
  box-shadow: 0 10px 22px rgba(var(--ink-rgb), 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.wu-story-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.wu-story-icon-invert {
  object-fit: contain !important;
  padding: 13px;
  filter: brightness(0) invert(1);
}
.wu-story-icon-photo {
  background: var(--surface-fill);
}
.wu-story-icon-neutral {
  background: var(--surface-fill);
  color: var(--ink);
}
.wu-story-icon-neutral svg {
  width: 24px;
  height: 24px;
}
/* No tile/background at all -- the mark itself, for Sol, Sol Rising and
   About, where a boxed icon read as unwanted chrome around something that
   should just sit on the page. */
.wu-story-icon-bare {
  border-radius: 0;
  box-shadow: none;
  background: none;
  overflow: visible;
  color: var(--ink);
}
.wu-story-icon-bare img {
  width: 100%;
  height: 100%;
  /* The real orb asset isn't alpha-transparent (white background baked in,
     by design -- it's meant for email clients too), so cover + a circular
     crop keeps the white corners from ever showing, and reads bigger and
     bolder than contain would inside the same box. */
  object-fit: cover;
  border-radius: 50%;
}
.wu-story-icon-bare svg {
  width: 40px;
  height: 40px;
}
/* Admin's gear: a brushed-steel gradient stroke (defined on the SVG itself,
   see scripts/generate-website-unlocked.js's wu-gear-metal gradient), not
   the page's ink color or a flat grey -- a small drop-shadow adds the depth
   a flat line can't, so it actually reads as metal as it spins. */
.wu-story-icon-spin {
  color: #8e8e93;
}
.wu-story-icon-spin svg {
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.28));
}
@keyframes wu-gear-spin {
  to {
    transform: rotate(360deg);
  }
}
.wu-story-icon-spin svg {
  width: 30px;
  height: 30px;
  animation: wu-gear-spin 8s linear infinite;
}
/* Gear and About's tetris block, sized to match Sol's orb (92px) -- same
   technique as the orb: the flex slot stays 56px so every row still
   aligns, the mark itself overflows larger via absolute centering. The
   gear's own rotation keyframe has to include that same centering
   translate on every step (same reason the orb's spin did), since a
   plain rotate() would drop it and the gear would drift off-center. */
.wu-story-icon-big {
  position: relative;
  overflow: visible;
}
.wu-story-icon-big svg {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 56px;
  height: 56px;
  transform: translate(-50%, -50%);
}
@keyframes wu-gear-spin-centered {
  from {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}
.wu-story-icon-big.wu-story-icon-spin svg {
  animation: wu-gear-spin-centered 8s linear infinite;
}
/* Sol / Sol Rising: the real orb render has its own soft glow margin, so
   at the standard 56px slot it reads smaller than the other icons even in
   the same box. Keep the flex slot at 56px -- same as every other icon,
   so titles/text still start at the same x position across every row --
   but let the image overflow larger via absolute positioning, centered on
   top of that slot. Also spins, matching the real .sol-orb animation on
   the live site (sol.css: sol-spin 10s linear). */
.wu-story-icon-orb {
  position: relative;
  overflow: visible;
}
/* Keyframes must include the centering translate on every step -- a CSS
   animation replaces the whole transform value, it doesn't compose with
   the base rule's, so a keyframe with only rotate() was dropping the
   centering and making the orb drift instead of spinning in place. */
@keyframes wu-orb-spin {
  from {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}
.wu-story-icon-orb img {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 92px;
  height: 92px;
  transform: translate(-50%, -50%);
  animation: wu-orb-spin 10s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .wu-story-icon-spin svg,
  .wu-story-icon-big.wu-story-icon-spin svg,
  .wu-story-icon-orb img {
    animation: none;
  }
}
/* Schedule a Chat: the real Connect-section button's dark-circle-plus-
   cream-glyph colors, fixed (not theme-toggled) since it's reproducing a
   specific existing UI element. The real .social-button is a translucent
   glass pill that only reads correctly on the Connect section's own dark
   background -- a solid fill here instead, so it looks right sitting on
   either a light or dark card. */
.wu-story-icon-round {
  border-radius: 999px;
  background: #11100e;
  color: #f7f3eb;
  box-shadow: none;
}
.wu-story-icon-round svg {
  width: 22px;
  height: 22px;
}
.wu-story-body {
  flex: 1;
  min-width: 0;
}
.wu-story-date {
  margin: 0 0 4px;
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.wu-story-title {
  margin: 0 0 6px;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.wu-story-title a {
  color: inherit;
  text-decoration: none;
}
.wu-story-text {
  margin: 0;
  font-size: 0.86rem;
  color: var(--muted);
  line-height: 1.52;
  /* No max-width here -- the card itself is already the right reading
     width; a ch-based cap on top of that was wrapping well short of the
     actual available space. */
}
.wu-story-stack {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 12px;
}
.wu-story-stack .svc {
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(var(--ink-rgb), 0.08);
  border: 1px solid rgba(var(--ink-rgb), 0.16);
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--ink);
}
/* Right-aligned "Visit" link, a sibling of the icon+body row rather than
   sitting inline inside the text -- every entry with a real page gets
   one, not just Sol Rising's case-study link (which moved here too). */
.wu-story-visit {
  flex: none;
  align-self: center;
  white-space: nowrap;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(var(--ink-rgb), 0.16);
}
.wu-story-visit:hover {
  background: rgba(var(--ink-rgb), 0.06);
}
@media (max-width: 640px) {
  .wu-story-visit {
    align-self: flex-start;
  }
}

/* ---- the cost section: a real, slightly askew, retro dot-matrix
   register receipt -- faded violet thermal-printer ink, paper torn on
   both ends, no glass frame around it (it's a photographed physical
   object sitting directly on the page, not UI chrome). ---- */
.wu-receipt-wrap {
  display: flex;
  justify-content: center;
  padding: 20px 0 32px;
}
.wu-receipt {
  /* Narrower than its old side-by-each-other width, so it reads as a real
     tall, narrow paper strip instead of a squat card. */
  width: min(330px, 82vw);
  background: #efe9d8;
  color: #5a4a7a;
  font-family: "Courier New", ui-monospace, "SF Mono", Menlo, monospace;
  padding: 46px 28px 50px;
  position: relative;
  transform: rotate(-2.4deg);
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3), 0 4px 14px rgba(0, 0, 0, 0.18);
  /* An irregular tear, not a uniform repeating sawtooth -- varying tooth
     width/depth (computed once, not hand-tuned) so it reads as actually
     torn, like the reference photo, not a mechanically perfect die-cut. */
  clip-path: polygon(
    4.7% 1.6%, 8.2% 2.4%, 13.3% 4.2%, 18.9% 1.8%, 22.9% 1.6%, 26.2% 3.5%, 28.8% 2.3%,
    33.6% 3.7%, 36.9% 3.9%, 42.2% 1.5%, 47.5% 4.3%, 51.2% 2.1%, 57.1% 2.8%, 59.9% 1.9%,
    65.4% 3.9%, 70.7% 4.4%, 75.1% 5.4%, 78.9% 3.7%, 84.3% 4.0%, 89.8% 3.8%, 94.8% 1.7%,
    98.1% 2.7%, 100% 2.4%,
    100% 96.8%,
    95.8% 96.0%, 92.9% 98.3%, 90.1% 96.5%, 84.1% 97.6%, 80.2% 94.9%, 75.7% 97.4%,
    71.2% 97.5%, 67.8% 96.7%, 62.1% 96.9%, 57.3% 97.2%, 51.7% 94.7%, 48.5% 97.4%,
    44.9% 98.4%, 41.6% 95.4%, 36.2% 95.8%, 31.8% 95.9%, 25.8% 97.0%, 22.7% 95.6%,
    19.6% 96.1%, 14.8% 94.8%, 11.4% 97.7%, 7.6% 97.0%, 2.9% 97.4%
  );
}
.r-texture {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.55;
  mix-blend-mode: multiply;
  background-image:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.03) 0px, transparent 1px, transparent 3px),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.025) 0px, transparent 1px, transparent 4px),
    radial-gradient(circle at 20% 20%, rgba(90, 74, 122, 0.08), transparent 40%),
    radial-gradient(circle at 80% 80%, rgba(90, 74, 122, 0.08), transparent 45%);
}
.r-head {
  text-align: center;
  margin-bottom: 16px;
  position: relative;
}
.r-sub {
  margin: 0;
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.75;
}
.r-store {
  margin: 8px 0;
  font-weight: 700;
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #5a4a7a;
  text-shadow: 0.4px 0 0 currentColor;
}
.r-dash {
  border-top: 1px dashed rgba(90, 74, 122, 0.45);
  margin: 14px 0;
  position: relative;
}
.r-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin: 15px 0;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  position: relative;
}
.r-label {
  white-space: nowrap;
}
.r-line {
  flex: 1;
  border-bottom: 1px dotted rgba(90, 74, 122, 0.5);
  position: relative;
  top: -4px;
  min-width: 10px;
}
.r-amt {
  white-space: nowrap;
  font-weight: 700;
}
.r-amt.placeholder {
  font-style: italic;
  font-weight: 400;
  opacity: 0.7;
}
.r-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.03em;
  border-top: 1px dashed rgba(90, 74, 122, 0.5);
  margin-top: 8px;
  padding-top: 12px;
  position: relative;
}
.r-foot {
  text-align: center;
  margin: 22px 0 0;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  opacity: 0.8;
  line-height: 1.7;
  position: relative;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wu-receipt {
    box-shadow: 0 30px 60px rgba(0, 0, 0, 0.6), 0 4px 14px rgba(0, 0, 0, 0.4);
  }
}
:root[data-theme="dark"] .wu-receipt {
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.6), 0 4px 14px rgba(0, 0, 0, 0.4);
}

/* ---- cost section: a second full-bleed hero-artwork band (same image,
   same object-fit/scrim technique as .wu-hero-art), breaking out of
   .wu-wrap's max-width the same way .wu-hero does, since this is the
   other deliberate place this page goes bright/full-color. The receipt
   keeps its own fixed cream/ink "real printed object" styling untouched
   (see the file banner comment), but now floats on its own liquid-glass
   shelf (.wu-receipt-shelf) above the art, instead of sitting directly on
   the page background -- same move as the closer beside it. ---- */
.wu-cost {
  position: relative;
  /* Shorter now that the receipt and glossary sit side by side instead of
     stacked -- the band only needs to be as tall as that row. */
  padding: clamp(48px, 7vh, 72px) clamp(20px, 6vw, 88px);
  margin-bottom: -1px;
  overflow: hidden;
  isolation: isolate;
}
.wu-cost-art {
  position: absolute;
  inset: 0;
  z-index: -1;
}
.wu-cost-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 60%;
}
.wu-cost-art::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 9, 8, 0.34), rgba(10, 9, 8, 0.5) 55%, rgba(10, 9, 8, 0.34));
}
:root[data-theme="dark"] .wu-cost-art::after {
  background: linear-gradient(180deg, rgba(5, 4, 4, 0.52), rgba(5, 4, 4, 0.66) 55%, rgba(5, 4, 4, 0.52));
}
.wu-cost-inner {
  position: relative;
  z-index: 1;
  max-width: 1120px;
  margin: 0 auto;
}
.wu-cost .wu-section-head h2,
.wu-cost .wu-section-sub {
  color: #fffaf3;
}
.wu-cost .wu-section-sub {
  color: rgba(255, 250, 243, 0.74);
}
/* Stacked, not side by side -- receipt, then a plain-English glossary of
   what's actually on it, then the closer at the very bottom of the page. */
.wu-cost-stack {
  display: flex;
  align-items: stretch;
  gap: 28px;
  flex-wrap: wrap;
}
.wu-receipt-shelf {
  /* Narrower share of the row than the glossary -- the receipt itself is
     already a narrow paper strip, so giving it equal flex-basis as the
     glossary left a lot of dead space around it. */
  flex: 1 1 36%;
  min-width: 280px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  border-radius: 28px;
}
@media (max-width: 760px) {
  .wu-cost-stack {
    flex-direction: column;
  }
}

/* ---- glossary: reuses each receipt row's own "detail" copy (same
   website-unlocked-data.json costs array) as a plain-language explainer
   for a visitor who doesn't already know what Resend or Cloudflare are. ---- */
.wu-glossary {
  flex: 1 1 60%;
  padding: 26px 30px;
  border-radius: 24px;
}
.wu-glossary-head {
  margin: 0 0 16px;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: 1.02rem;
  text-transform: uppercase;
  color: var(--ink);
}
.wu-glossary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px 28px;
}
.wu-glossary-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.wu-glossary-term {
  font-weight: 700;
  font-size: 0.88rem;
  color: var(--ink);
}
.wu-glossary-def {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.48;
  color: var(--muted);
}

/* ---- daily tools: a small real-link addendum under the receipt/glossary,
   plain small-caps label + a row of glass pills, not another full widget --
   real URLs only (claude.com/product/claude-code, ghostty.org, herdr.dev,
   cursor.com), confirmed, never guessed. ---- */
.wu-tools {
  margin-top: 30px;
  text-align: center;
}
.wu-tools-head {
  margin: 0 0 12px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 250, 243, 0.68);
}
.wu-tools-row {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
}
.wu-tools-pill {
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid rgba(255, 250, 243, 0.3);
  background: rgba(255, 250, 243, 0.08);
  font-size: 0.82rem;
  font-weight: 600;
  text-decoration: none;
  color: #fffaf3;
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  transition: transform 180ms ease, background 180ms ease;
}
.wu-tools-pill:hover,
.wu-tools-pill:focus-visible {
  background: rgba(255, 250, 243, 0.18);
  transform: translateY(-1px);
}

/* ---- closer: a real way to actually reach out, floating on its own
   glass panel beside the receipt -- the page had no path to message or
   schedule time with Jason at all until now; reuses the site's own
   ?connect=open / ?schedule=open deep links (script.js), same as the
   welcome email and Sol already do. ---- */
/* Below the artwork band now, on the plain page background -- a single
   narrower, centered widget, not stretched full-width like the two above.
   Layout matches about.html's own "Connect / Let's talk" widget: an
   eyebrow, a big Archivo Black heading, one centered lede, then every
   action (message, schedule, socials) as one row of equal pill buttons --
   same structure as .ab-connect/.ab-eyebrow/.ab-h2/.ab-lede/.ab-cta/.ab-btn,
   just using this page's own --wu-c1..6 palette for the glow instead of
   about's block colors. */
.wu-closer-wrap {
  display: flex;
  justify-content: center;
  padding: clamp(56px, 8vh, 84px) clamp(20px, 6vw, 88px) clamp(70px, 10vh, 100px);
}
.wu-closer {
  position: relative;
  width: min(820px, 100%);
  padding: clamp(36px, 5.5vw, 56px) clamp(24px, 5vw, 48px);
  border-radius: 34px;
  text-align: center;
}
.wu-closer::before {
  content: "";
  position: absolute;
  inset: -30px -40px;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(closest-side at 14% 30%, rgba(var(--wu-c4), 0.5), transparent 72%),
    radial-gradient(closest-side at 84% 24%, rgba(var(--wu-c3), 0.46), transparent 72%),
    radial-gradient(closest-side at 22% 86%, rgba(var(--wu-c5), 0.46), transparent 72%),
    radial-gradient(closest-side at 80% 82%, rgba(var(--wu-c1), 0.42), transparent 72%);
  filter: blur(28px);
  opacity: 0.8;
}
:root[data-theme="dark"] .wu-closer::before {
  opacity: 0.5;
}
.wu-closer-eyebrow {
  margin: 0 0 14px;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(var(--ink-rgb), 0.66);
}
.wu-closer-title {
  margin: 0 auto;
  max-width: 14ch;
  font-family: "Archivo Black", Impact, sans-serif;
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  line-height: 1.04;
  text-transform: uppercase;
  color: var(--ink);
}
.wu-closer-text {
  margin: 18px auto 0;
  max-width: 48ch;
  color: rgba(var(--ink-rgb), 0.82);
  font-size: 1rem;
  line-height: 1.58;
}
.wu-closer-actions {
  display: flex;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 28px;
}
/* One extra button vs. about.html's own version of this row (it has no
   Schedule a chat) -- tighter padding/font than .ab-btn so all 5 still
   fit on one line at the same widget width. */
.wu-closer-btn {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 10px 15px;
  border-radius: 13px;
  border: 1px solid rgba(var(--ink-rgb), 0.22);
  font-size: 0.8rem;
  font-weight: 700;
  text-decoration: none;
  color: var(--ink);
  transition: transform 180ms ease;
}
.wu-closer-btn:hover,
.wu-closer-btn:focus-visible {
  transform: translateY(-2px);
}
.wu-closer-btn-solid {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
/* Same real mail icon/sizing as about.html's .ab-ico (the Connect
   dialog's own mail glyph), not a drawn substitute. */
.wu-closer-ico {
  width: 16px;
  height: 16px;
  margin-right: 7px;
  flex: none;
}

