/* ============================================================
   DDG HOLDINGS — Component styles
   Every color / font / spacing value below is a var() from tokens.css.
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

h1, h2, p, ol, li {
  margin: 0;
}

a {
  color: inherit;
}

/* ---------- Layout helpers ---------- */

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section {
  padding-block: var(--space-6);
}

.section-bleed {
  padding-block: var(--space-6);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 200;
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
  font-family: var(--font-body);
  padding: var(--space-2) var(--space-3);
  transform: translateY(-100%);
  transition: transform 150ms ease-out;
}

.skip-link:focus {
  transform: translateY(0);
}

/* ---------- Focus ---------- */

a:focus-visible,
button:focus-visible,
.carousel:focus-visible {
  outline: 2px solid var(--color-leaf);
  outline-offset: 2px;
}

/* ---------- Eyebrow ---------- */

.eyebrow {
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  font-size: var(--text-label);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
}

.eyebrow--on-forest {
  color: var(--color-lime);
}

/* ---------- Links (shared component) ---------- */

.prose a,
.footer__email,
.footer__fine-print a {
  color: var(--text-primary);
  text-decoration: none;
  border-bottom: 1.5px solid var(--color-line);
  transition: border-color 150ms ease-out;
}

.prose a:hover,
.footer__email:hover,
.footer__fine-print a:hover {
  border-bottom: 2px solid var(--color-leaf);
}

.footer__fine-print a {
  /* invisible padding expands the tap target to 44px without affecting layout or look */
  display: inline-block;
  padding: 12px 4px;
  margin: -12px -4px;
}

/* ---------- Button (shared component, only one on the page) ---------- */

.button {
  display: inline-block;
  background: var(--btn-bg);
  color: var(--btn-text);
  font-family: var(--font-body);
  font-weight: 500;
  text-decoration: none;
  border-radius: var(--radius-btn);
  padding: 14px 28px;
  margin-top: var(--space-4);
  transition: background-color 150ms ease-out, transform 150ms ease-out;
}

.button:hover {
  background: var(--btn-bg-hover);
  transform: translateY(-1px);
}

.button:active {
  transform: translateY(0);
}

/* ---------- Tag / pill ---------- */

.tag {
  display: inline-block;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  font-size: var(--text-label);
  background: var(--tag-bg);
  color: var(--tag-text);
  border-radius: var(--radius-tag);
  padding: 6px 14px;
}

.mono-note {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--text-secondary);
}

.todo-inline {
  font-family: var(--font-mono);
  color: var(--color-leaf);
}

/* ---------- Nav ---------- */

.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 200ms ease-out, border-color 200ms ease-out;
}

.nav.scrolled {
  background: var(--bg-page);
  border-bottom: 1px solid var(--border-default);
}

.nav__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  padding-block: var(--space-2);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav__wordmark {
  font-family: var(--font-mono);
  font-weight: 500;
  letter-spacing: var(--tracking-label);
  text-decoration: none;
  color: var(--text-primary);
  /* invisible padding expands the tap target to 44px without affecting layout or look */
  padding: 10px 4px;
  margin: -10px -4px;
}

.nav__links {
  display: flex;
  gap: var(--space-3);
}

.nav__links a {
  text-decoration: none;
  color: var(--text-primary);
  font-size: var(--text-small);
  border-bottom: 1.5px solid transparent;
  transition: border-color 150ms ease-out;
  padding: 10px 4px;
  margin: -10px -4px;
}

.nav__links a:hover {
  border-bottom: 2px solid var(--color-leaf);
}

/* ---------- Hero ---------- */

.hero {
  /* 90svh (not 100) — with the shorter thesis, a full-height hero left a large
     empty band below the button before the forest strip began. This keeps the
     "full viewport" feel without the leftover dead space. */
  min-height: 90svh;
  display: flex;
  align-items: center;
  padding-top: var(--space-5);
  padding-bottom: var(--space-5);
}

.hero__grid {
  display: grid;
  /* true 50/50 — the image needs to hold equal visual weight to the thesis,
     not sit as a small square in a narrow column. */
  grid-template-columns: 1fr 1fr;
  /* stretch (not center): both columns' boxes span the exact same height —
     the text column's natural height sets the row height, and .hero__visual
     stretches to match it exactly. This is what makes the eyebrow's top and
     the image's top share one edge, and the button zone's bottom and the
     image's bottom share the other — a deliberate, always-exact relationship
     instead of two independently-sized blocks that happen to be centered. */
  align-items: stretch;
  gap: var(--space-5);
  width: 100%;
}

.hero__visual {
  width: 100%;
  /* paper, not forest — this is a loading-fallback only. The photo itself is
     used exactly as provided (rounded card, white margin, product elements
     breaking its edges by design) and sits directly on the page background,
     which is paper — so the fallback should match that, not force a forest
     block behind it. */
  background: var(--bg-page);
}

.hero__visual-photo {
  display: block;
  width: 100%;
  height: 100%;
  /* contain, not cover — this image must never be cropped. It's used exactly
     as provided; the rounded corners, white margin, and elements breaking
     the card's edges are the original design and stay intact.
     object-position:top (not the center default) puts the image's own top
     edge flush against the container's top — which, via align-items:stretch
     on .hero__grid, is the same line the eyebrow starts on. That's the
     deliberate top alignment; the leftover space this leaves at the bottom
     (since the image is width-limited and shorter than the text column) is
     an intentional, constant offset from the button zone, not a near-miss. */
  object-fit: contain;
  object-position: top;
}

@media (max-width: 768px) {
  .hero {
    /* content-driven height on mobile — 90svh was tuned for the desktop
       two-column layout; stacked with the (now hidden) image, it left large
       dead zones above/below it. Text + spacing now define the section's
       height. padding-bottom falls back to the base var(--space-5) below —
       zeroing it (an earlier attempt) left the button flush against the
       forest strip's color change with no paper-colored breathing room at
       all, unlike every other section-to-section transition on the page. */
    min-height: auto;
  }

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

  .hero__visual {
    /* hidden on mobile — the product photo's detail doesn't read at this
       size, and the section is stronger ending on the thesis + button
       than on a shrunken image. Real photography returns in the Pipeline
       strip and Portfolio teaser right below. */
    display: none;
  }
}

.hero__thesis {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-hero);
  line-height: var(--leading-tight);
}

.hero__thesis span {
  display: block;
}

.accent {
  color: var(--text-accent);
  font-style: italic;
}

.hero__subline {
  font-family: var(--font-body);
  color: var(--text-secondary);
  max-width: 44ch;
  margin-top: var(--space-3);
}

/* Hero signature reveal: eyebrow + thesis lines only, 80ms stagger, 600ms total */

.reveal-line {
  opacity: 0;
  transform: translateY(20px);
  animation: reveal-in 360ms ease-out both;
  animation-delay: var(--line-delay, 0ms);
}

@keyframes reveal-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal-line {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ---------- Generic section reveal-on-scroll ---------- */

.reveal-on-scroll {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 500ms ease-out, transform 500ms ease-out;
}

.reveal-on-scroll.in-view {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal-on-scroll {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- Why (editorial paragraph) ---------- */

.section__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-h2);
  line-height: var(--leading-head);
  max-width: 14ch;
  margin-bottom: var(--space-4);
}

.prose {
  max-width: 56ch;
}

.prose p + p {
  margin-top: var(--space-3);
}

/* ---------- Pillars (numbered rows, not cards) ---------- */

.section-bleed.how {
  background: var(--bg-section-alt);
}

/* ---------- Pipeline (brand carousel, full-bleed forest) ---------- */

.section-bleed.pipeline {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
}

.carousel-wrap {
  margin-top: var(--space-5);
}

.carousel {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  list-style: none;
  margin: 0;
  padding: 0 0 var(--space-2) 0;
  scrollbar-width: none;
}

.carousel::-webkit-scrollbar {
  display: none;
}

.carousel__slide {
  flex: 0 0 auto;
  scroll-snap-align: start;
  width: min(240px, 65vw);
  aspect-ratio: 3 / 4;
  display: flex;
  flex-direction: column;
  background: var(--bg-page);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  padding: var(--space-3);
}

.carousel__slide--lime {
  background: var(--color-lime);
}

.carousel__slide--type {
  background: var(--bg-inverse);
  border-color: var(--color-paper);
  align-items: center;
  justify-content: center;
  text-align: center;
}

.carousel__art,
.carousel__color-block {
  width: 100%;
  min-height: 0;
  flex: 1 1 auto;
  border-radius: var(--radius-card);
}

.carousel__art {
  height: auto;
  fill: none;
  stroke: var(--color-forest);
  stroke-width: 1.5;
}

.carousel__color-block--a {
  background: var(--color-forest);
}

.carousel__color-block--b {
  background: var(--color-sage);
}

/* Brand 01 — the one photographic card; the rest stay flat color/type by
   design (see CLAUDE.md pipeline spec). Photo fills the card edge to edge
   instead of sitting inset like the SVG/color-block slides, so the slide's
   own padding is zeroed and reapplied to just the label lines below. */
.carousel__slide--photo {
  padding: 0;
  overflow: hidden;
}

.carousel__photo {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  flex: 1 1 auto;
  object-fit: cover;
}

.carousel__slide--photo .carousel__label-brand {
  padding-inline: var(--space-3);
}

.carousel__slide--photo .carousel__label-status {
  padding-inline: var(--space-3);
  padding-bottom: var(--space-3);
}

.carousel__label-brand {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-small);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--text-secondary);
  margin-top: var(--space-2);
}

.carousel__label-status {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-label);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--text-secondary);
  margin-top: var(--space-1);
}

.carousel__slide--type .carousel__label-brand,
.carousel__slide--type .carousel__label-status {
  color: var(--text-on-inverse);
}

.carousel__controls {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.carousel__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1.5px solid var(--color-paper);
  border-radius: var(--radius-btn);
  color: var(--color-paper);
  cursor: pointer;
  transition: border-color 150ms ease-out, color 150ms ease-out;
}

.carousel__btn svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
}

.carousel__btn:hover {
  border-color: var(--color-leaf);
  color: var(--color-leaf);
}

@media (prefers-reduced-motion: reduce) {
  .carousel {
    scroll-behavior: auto;
  }
}

.pillars {
  list-style: none;
  padding: 0;
  margin-top: var(--space-5);
}

.pillar {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  padding-block: var(--space-4);
  /* --border-default is tuned for paper; on lime it disappears, so use sage —
     tokens.css rule 4 already approves sage for direct use on lime. */
  border-top: 1px solid var(--color-sage);
}

.pillar:last-child {
  border-bottom: 1px solid var(--color-sage);
}

.pillar__number {
  font-family: var(--font-display);
  font-size: var(--text-h2);
  color: var(--color-forest);
  transition: transform 250ms ease-out;
  flex-shrink: 0;
  width: 2ch;
}

.pillar__name {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-h3);
  position: relative;
  padding-bottom: 2px;
  flex-shrink: 0;
}

.pillar__name::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0%;
  height: 2px;
  background: var(--color-leaf);
  transition: width 250ms ease-out;
}

.pillar:hover .pillar__name::after {
  width: 100%;
}

.pillar__desc {
  font-family: var(--font-body);
  color: var(--text-secondary);
  max-width: 42ch;
}

.pillar:hover .pillar__number {
  transform: translateX(8px);
}

@media (prefers-reduced-motion: reduce) {
  .pillar__number,
  .pillar__name::after {
    transition: none;
  }
}

/* ---------- Portfolio teaser ---------- */

.teaser {
  display: flex;
  gap: var(--space-5);
  align-items: center;
  background: var(--bg-page);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  padding: var(--space-5);
  margin-top: var(--space-5);
}

.teaser__copy {
  flex: 1 1 55%;
}

.teaser__brand-line {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--text-secondary);
  margin-top: var(--space-3);
}

.teaser__sentence {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  margin-top: var(--space-2);
  max-width: 32ch;
}

.teaser__visual {
  flex: 1 1 30%;
  display: flex;
  justify-content: center;
}

.bottle-svg {
  width: 100%;
  max-width: 160px;
  height: auto;
}

.bottle-outline,
.bottle-cap {
  stroke: var(--color-forest);
}

.tablet {
  stroke: var(--color-forest);
  transform: translateY(-24px);
  opacity: 0;
}

.teaser__visual.in-view .tablet {
  animation: tablet-drop 700ms ease-out forwards;
}

@keyframes tablet-drop {
  0% {
    transform: translateY(-24px);
    opacity: 0;
  }
  40% {
    opacity: 1;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tablet {
    transform: none;
    opacity: 1;
  }

  .teaser__visual.in-view .tablet {
    animation: none;
  }
}

.mono-note {
  display: block;
  margin-top: var(--space-4);
}

/* ---------- Founder letter ---------- */

.section-bleed.founder {
  background: var(--bg-inverse);
  color: var(--text-on-inverse);
}

.founder__letter {
  font-family: var(--font-display);
  font-size: 1.5rem;
  line-height: var(--leading-head);
  max-width: 60ch;
}

.founder__signatures {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
  margin-top: var(--space-5);
}

.founder__signature-name {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--text-h3);
}

.founder__signature-title {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--color-lime);
  margin-top: var(--space-1);
}

.founder__divider {
  border: none;
  /* --border-default is tuned for paper and is invisible on forest; paper itself
     reads as a clean hairline against forest — same treatment already used for
     the pipeline section's typography-card borders. */
  border-top: 1px solid var(--color-paper);
  margin: var(--space-5) 0 0 0;
}

.founder__cards {
  display: grid;
  /* Capped card width — these are a closing element of the section, not a
     full-viewport moment. minmax(0, 300px) keeps each card in the 260-320px
     range and justify-content:start keeps the row left-anchored, well
     inside the container, matching the page's asymmetric layout rule. */
  grid-template-columns: repeat(3, minmax(0, 300px));
  justify-content: start;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.founder__photo {
  display: block;
  width: 100%;
  /* height:auto is required here — the img's width/height HTML attributes
     (there for CLS prevention) map to explicit CSS sizing hints, so once
     width:100% makes width definite, height was ALSO already definite (from
     the attributes) and aspect-ratio had nothing left to resolve, silently
     no-oping and rendering at the attributes' raw pixel height instead of
     a square. height:auto clears that so aspect-ratio actually drives it. */
  height: auto;
  aspect-ratio: 1 / 1;
  /* shown while the lazy-loaded photo paints, and as the fallback for any slot
     still using the empty-div placeholder */
  background: var(--color-paper);
  object-fit: cover;
}

.founder__card-name {
  font-family: var(--font-body);
  font-weight: 700;
  margin-top: var(--space-3);
}

.founder__card-title {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--color-lime);
  margin-top: var(--space-1);
}

.founder__card-belief {
  font-family: var(--font-body);
  margin-top: var(--space-2);
}

@media (max-width: 768px) {
  .founder__signatures {
    grid-template-columns: 1fr;
  }

  .founder__cards {
    /* stack at the same capped card width, not full-bleed */
    grid-template-columns: minmax(0, 300px);
  }
}

/* ---------- Footer ---------- */

.footer__line {
  font-family: var(--font-display);
  font-size: var(--text-h3);
  white-space: nowrap;
}

@media (max-width: 480px) {
  .footer__line {
    white-space: normal;
  }
}

.footer__email {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--text-h2);
  margin-top: var(--space-3);
}

.footer__fine-print {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--text-secondary);
  margin-top: var(--space-5);
}

/* ---------- Responsive ---------- */

@media (max-width: 768px) {
  .teaser {
    flex-direction: column;
    align-items: flex-start;
    padding: var(--space-4);
  }

  .teaser__visual {
    order: -1;
    max-width: 120px;
  }

  .pillar {
    gap: var(--space-1) var(--space-3);
  }
}

@media (max-width: 480px) {
  .nav__links {
    gap: var(--space-2);
  }

  .pillar__desc {
    flex-basis: 100%;
  }
}
