/* ==========================================================================
   site.css — the ArkNode Studio marketing page (index.html).

   Layout vocabulary
   -----------------
   .shell        1080px measure with a fluid gutter. Every full-width band
                 wraps its content in one.
   .band         A page section: hairline top rule, generous vertical
                 rhythm, and a scroll-margin that clears the sticky header.
   .eyebrow      A 30px terracotta rule plus a wide-tracked uppercase label.
                 It is the page's one structural device and it appears once
                 per band, marking where a new subject starts.

   Breakpoints are 1000px (the three- and five-across grids collapse) and
   760px (phone: nav drops, controls stack, wireframe detail thins out).
   Both come straight from the approved design.
   ========================================================================== */

/* ==========================================================================
   Shared layout
   ========================================================================== */

.shell {
  max-width: 1080px;
  margin: 0 auto;
  padding-inline: clamp(20px, 3vw, 32px);
}

.band {
  border-top: 1px solid var(--line);
  scroll-margin-top: 68px;
}

.band > .shell {
  padding-block: clamp(56px, 8vw, 96px);
}

.eyebrow {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* Hangs off the first line rather than the block's centre, so a label that
   wraps to two lines does not leave the rule floating between them. */
.eyebrow::before {
  content: '';
  flex: none;
  width: 30px;
  height: 1px;
  margin-top: 8px;
  background: var(--accent);
}

.eyebrow-label {
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* One step under the old 27–40px scale. The hero is the only display type on
   the page, so band headings only have to out-rank their own section — they
   read as headings against 17px body copy without competing with the hero.
   `.about-title` below shares this scale and moves with it. */
.band-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(24px, 2.6vw, 30px);
  line-height: 1.14;
  letter-spacing: -0.022em;
  margin: 18px 0 0;
}

.band-lead {
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink-body);
  margin: 14px 0 0;
  max-width: 52ch;
}

/* The closing line under the `#cost` card grid. Same reading weight as
   `.band-lead` but wider and set off from the grid, because it answers a
   different question: not what the band is about, but what happens next. */
.band-close {
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink-body);
  margin: clamp(28px, 3vw, 36px) 0 0;
  max-width: 68ch;
}

/* --- Buttons ---
   Three weights: filled terracotta for the primary action, outlined for
   the secondary, and an ink outline for the header CTA that inverts on
   hover. Every one clears a 48px touch target. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 50px;
  padding: 12px 20px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease-out, border-color 160ms ease-out,
    color 160ms ease-out;
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

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

.btn-secondary {
  background: var(--surface);
  border-color: var(--line);
  color: var(--ink);
}

.btn-secondary:hover {
  border-color: var(--line-strong);
  color: var(--ink);
}

/* ==========================================================================
   Header
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.site-header > .shell {
  height: 68px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--ink);
  text-decoration: none;
}

.wordmark svg {
  flex: none;
}

.wordmark-text {
  font-family: var(--font-display);
  font-size: 17.5px;
  font-weight: 600;
  letter-spacing: -0.012em;
  white-space: nowrap;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  font-size: 15px;
  color: var(--ink-body);
  text-decoration: none;
  transition: color 160ms ease-out;
}

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

.header-cta {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 17px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 160ms ease-out, color 160ms ease-out;
}

.header-cta:hover {
  background: var(--ink);
  color: var(--on-ink);
}

/* ==========================================================================
   Hero

   The one orchestrated moment on the site. On load the backdrop grid draws
   itself line by line, the copy rises in reading order, the browser mock
   fills from flat grey into real content, and an ink stroke finally lands
   under "look like it". Roughly 3.6s end to end; reduced motion skips to the
   finished state.
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: clamp(460px, calc(78svh - 68px), 700px);
}

.hero-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.7;
  /* Fades the grid out toward the copy so text always wins the contrast. */
  mask-image: linear-gradient(
    28deg,
    #000 0%,
    rgba(0, 0, 0, 0.5) 32%,
    transparent 62%
  );
  -webkit-mask-image: linear-gradient(
    28deg,
    #000 0%,
    rgba(0, 0, 0, 0.5) 32%,
    transparent 62%
  );
}

.hero-grid svg {
  display: block;
  max-width: none;
}

.hero-grid line {
  stroke: var(--grid-line);
  stroke-width: 1;
}

.hero-grid line.is-major {
  stroke: var(--grid-line-major);
}

.hero-inner {
  position: relative;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(44px, 6vw, 64px) clamp(20px, 3vw, 32px);
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
}

.hero-copy {
  min-width: 0;
}

.hero-place {
  display: block;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink-muted);
  animation: hero-rise 480ms ease-out 700ms backwards;
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(33px, 8.4vw, 64px);
  line-height: 1.07;
  letter-spacing: -0.03em;
  color: var(--ink);
  margin: clamp(16px, 2vw, 22px) 0 0;
  max-width: 17ch;
  animation: hero-rise 480ms ease-out 760ms backwards;
}

.hero-title em {
  position: relative;
  font-style: italic;
  font-weight: 500;
  white-space: nowrap;
}

/* The ink stroke. preserveAspectRatio is off so the sweep always spans the
   phrase, and the viewBox (368x20) is cut to the rendered aspect ratio of
   "look like it" at 0.22em tall, so the scale stays uniform and the stroke
   keeps an even weight instead of fattening on its steep sections. Both the
   phrase width and the box height are em-based, so that ratio holds at every
   breakpoint. Overflow stays visible so the crests are not clipped. */
.hero-ink {
  position: absolute;
  left: 0;
  bottom: -0.16em;
  width: 100%;
  height: 0.22em;
  overflow: visible;
}

.hero-ink path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 0;
  animation: hero-ink 380ms ease-out 3200ms backwards;
}

.hero-dek {
  font-size: 17px;
  line-height: 1.68;
  color: var(--ink-body);
  margin: clamp(24px, 3vw, 30px) 0 0;
  border-top: 1px solid var(--line);
  padding-top: 20px;
  max-width: 54ch;
  animation: hero-rise 480ms ease-out 850ms backwards;
}

.hero-actions {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 22px;
  animation: hero-rise 480ms ease-out 920ms backwards;
}

.hero-buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.hero-terms {
  font-size: 14px;
  line-height: 1.75;
  color: var(--ink-muted);
  margin: 0;
}

/* Each clause is atomic, and the separator is glued to the clause before it,
   so a wrap happens between terms and never leaves a "·" starting a line. */
.hero-terms span {
  white-space: nowrap;
}

.hero-terms span:not(:last-child)::after {
  content: '\00a0·';
  padding-inline-end: 4px;
}

/* --- The browser mock --------------------------------------------------- */

.hero-morph {
  min-width: 0;
  animation: hero-rise 560ms ease-out 980ms backwards;
}

.morph {
  max-width: 430px;
  margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-morph);
  overflow: hidden;
}

.morph-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  animation: hero-grey 600ms ease 1250ms backwards;
}

.morph-dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--line);
}

.morph-dot-live {
  background: var(--accent);
}

.morph-url {
  width: 148px;
  height: 10px;
  margin-left: 10px;
  border-radius: 999px;
  background: var(--wire-chrome);
  border: 1px solid var(--wire-chrome-line);
  animation: hero-grey 600ms ease 1350ms backwards;
}

.morph-body {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.morph-banner {
  min-height: 104px;
  padding: 16px 14px;
  border-radius: 6px;
  background: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 8px;
  animation: hero-grey 700ms ease 1450ms backwards;
}

.morph-banner-line {
  height: 7px;
  border-radius: 999px;
  background: rgba(250, 247, 242, 0.9);
}

.morph-banner-line-soft {
  background: rgba(250, 247, 242, 0.5);
}

.morph-banner-cta {
  width: 58px;
  height: 15px;
  margin-top: auto;
  border-radius: 4px;
  background: var(--accent);
}

.morph-tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.morph-tile {
  padding: 7px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.morph-thumb {
  height: 30px;
  border-radius: 4px;
  background: var(--wire-tile);
}

.morph-thumb-warm {
  background: var(--wire-tile-warm);
}

.morph-bar {
  height: 5px;
  border-radius: 999px;
  background: var(--wire-bar);
}

.morph-bar-soft {
  background: var(--wire-bar-soft);
}

.morph-tile-cta {
  height: 12px;
  margin-top: 2px;
  border-radius: 4px;
  background: var(--accent);
}

.morph-footer {
  height: 16px;
  border-radius: 4px;
  background: var(--ink);
  animation: hero-grey 600ms ease 1950ms backwards;
}

/* Ragged widths on the mock's text bars. Uneven on purpose: equal-length
   bars read as a loading skeleton, varied ones read as real copy. */
.morph-banner-line { width: 62%; }
.morph-banner-line-soft { width: 42%; }
.morph-tile:nth-child(1) .morph-bar { width: 86%; }
.morph-tile:nth-child(1) .morph-bar-soft { width: 58%; }
.morph-tile:nth-child(2) .morph-bar { width: 78%; }
.morph-tile:nth-child(2) .morph-bar-soft { width: 52%; }
.morph-tile:nth-child(3) .morph-bar { width: 82%; }

/* Per-element entry timing. Kept together so the sequence can be read as a
   sequence instead of being scattered through the rules above. */
.morph-tile:nth-child(1) { animation: hero-grey 650ms ease 1650ms backwards; }
.morph-tile:nth-child(2) { animation: hero-grey 650ms ease 1750ms backwards; }
.morph-tile:nth-child(3) { animation: hero-grey 650ms ease 1850ms backwards; }

.morph [data-in] { animation: hero-appear 400ms ease backwards; }
.morph [data-in='2050'] { animation-delay: 2050ms; }
.morph [data-in='2170'] { animation-delay: 2170ms; }
.morph [data-in='2250'] { animation-delay: 2250ms; }
.morph [data-in='2330'] { animation-delay: 2330ms; }
.morph [data-in='2350'] { animation-delay: 2350ms; }
.morph [data-in='2410'] { animation-delay: 2410ms; }
.morph [data-in='2420'] { animation-delay: 2420ms; }
.morph [data-in='2430'] { animation-delay: 2430ms; }
.morph [data-in='2500'] { animation-delay: 2500ms; }
.morph [data-in='2510'] { animation-delay: 2510ms; }
.morph [data-in='2600'] { animation-delay: 2600ms; }
.morph [data-in='2750'] { animation-duration: 320ms; animation-delay: 2750ms; }
.morph [data-in='2820'] { animation-duration: 320ms; animation-delay: 2820ms; }
.morph [data-in='2890'] { animation-duration: 320ms; animation-delay: 2890ms; }
.morph [data-in='2900'] { animation-delay: 2900ms; }

@keyframes hero-line-v {
  from { stroke-dashoffset: 900; }
}

@keyframes hero-line-h {
  from { stroke-dashoffset: 1600; }
}

@keyframes hero-rise {
  from { opacity: 0; transform: translateY(12px); }
}

@keyframes hero-grey {
  from { background-color: var(--wire-grey); border-color: var(--wire-grey-line); }
}

@keyframes hero-appear {
  from { opacity: 0; }
}

/* The design referenced this animation on the underline but never defined
   it, so the closing beat of the sequence silently did nothing. pathLength
   is 100, so a full offset of 100 draws the stroke left to right. */
@keyframes hero-ink {
  from { stroke-dashoffset: 100; }
}

/* ==========================================================================
   Work
   ========================================================================== */

.work-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 28px;
  margin-top: clamp(32px, 4vw, 44px);
}

.work-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: inherit;
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.work-card:hover {
  transform: translateY(-4px);
  border-color: var(--line-strong);
  box-shadow: 0 12px 28px rgba(23, 19, 16, 0.08);
}

.work-shot {
  position: relative;
  aspect-ratio: 2 / 1;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}

.work-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.work-card:hover img {
  transform: scale(1.03);
}

.work-text {
  padding: 22px 22px 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.work-kind {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--evergreen);
}

/* Card titles hold a clear step below the band heading, which bottoms out at
   24px on a phone — at the old 22px they read as the same rank there. */
.work-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 20px;
  line-height: 1.25;
  letter-spacing: -0.012em;
  margin: 0;
}

.work-note {
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink-body);
  margin: 0;
}

/* --- Image placeholders ---
   No screenshots exist yet. Rather than a broken-looking empty box, the
   slot reuses the page's own eyebrow device and names what belongs there,
   so an unfilled slot reads as pending rather than failed. Replace the
   whole .slot element with an <img> when the asset lands. */
.slot {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 20px;
  text-align: center;
}

.slot::before {
  content: '';
  width: 28px;
  height: 1px;
  background: var(--accent);
}

.slot-label {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.slot-portrait {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink-muted);
}

/* ==========================================================================
   How we price

   The band carries no figures and no tiers, so there is no price element,
   no featured card and no per-card CTA. What is left is the card grid
   itself, holding the three things that shape a quote.
   ========================================================================== */

.plan-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin-top: clamp(32px, 4vw, 48px);
}

.plan {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}

.plan-body {
  padding: 26px 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  flex: 1;
}

/* Same step below the band heading as `.work-title`. */
.plan-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 19px;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 0;
}

/* The sentence that tells a prospect what a card is asking about, so it is
   set at reading weight rather than as fine print. The three are written to
   a near-equal length so their occupied heights stay close; the min-height
   keeps the hairline above `.plan-list` level across the row when one runs
   a line shorter. The measured 90px floor keeps the card contents aligned
   across the three-column range. Re-measure it if the sentences change
   length. */
.plan-for {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-body);
  margin: 12px 0 0;
  min-height: 90px;
}

.plan-list {
  list-style: none;
  margin: 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.plan-list li {
  display: flex;
  gap: 12px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-body);
}

/* An evergreen tick rule rather than a bullet glyph — the same hairline
   language as the eyebrow, at list scale. */
.plan-list li::before {
  content: '';
  flex: none;
  width: 9px;
  height: 1px;
  margin-top: 12px;
  background: var(--evergreen);
}

.care {
  margin-top: 28px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 24px clamp(20px, 3vw, 28px);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.care::before {
  content: '';
  width: 34px;
  height: 2px;
  background: var(--accent);
}

.care p {
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-body);
  margin: 0;
  max-width: 82ch;
}

.care strong {
  color: var(--ink);
  font-weight: 600;
}

/* ==========================================================================
   Process

   Numbered because it genuinely is a sequence — a client moves through
   these five stages in order, and the number is how they locate where the
   project currently is.
   ========================================================================== */

.steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  list-style: none;
  margin: clamp(32px, 4vw, 44px) 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface);
}

.step {
  padding: 26px 22px 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.step + .step {
  border-left: 1px solid var(--line);
}

.step-n {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--accent);
}

.step h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 19px;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 0;
}

.step p {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-body);
  margin: 0;
}

/* ==========================================================================
   About + contact
   ========================================================================== */

/* Primary and secondary, not a two-up. The founder's column is the wider
   track because it carries the band's heading and four paragraphs; the
   cofounder's panel is narrower and top-aligned, so it ends where his words
   end instead of stretching padding to match a column it cannot fill.
   `align-items: start` is what keeps that promise - do not switch it to
   `stretch` to "balance" the two. */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.62fr) minmax(0, 1fr);
  gap: clamp(36px, 4.5vw, 60px);
  align-items: start;
  margin-top: 18px;
}

.about-head {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.about-portrait {
  flex: none;
  width: 120px;
  height: 150px;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-card);
}

.about-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 35%;
  display: block;
}

/* Framing is a property of the photograph, not of the treatment. Both
   portraits share the card and the `object-position` above, and both are
   cut to the same 0.695 aspect; Jerrick's crop already sits the head in
   the card, while the founder's own frame stands further back, so his
   needs this zoom to land at the same head height. Re-measure this if
   `assets/portrait-2026-08.jpg` is ever recropped. */
.about-portrait--zoomed img {
  transform-origin: 58% 42%;
  transform: scale(1.6);
}

/* Title and role travel together as one flex child of the head, mirroring
   `.about-person-id` on the cofounder's side; the sizing the title carried
   as a direct child moves here so both lines hang from the top of the card
   beside the portrait. */
.about-title-id {
  flex: 1 1 220px;
  min-width: 0;
}

.about-title {
  font-family: var(--font-display);
  font-weight: 500;
  /* Same scale as `.band-title`; keep the two in step. */
  font-size: clamp(24px, 2.6vw, 30px);
  line-height: 1.14;
  letter-spacing: -0.022em;
  margin: 0;
}

/* His standing in the studio, in the page's own voice - his own word for
   it, unpadded. Same treatment as `.about-person-role`; keep the two in
   step. */
.about-title-role {
  font-size: 13.5px;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin: 6px 0 0;
}

.about-copy {
  margin-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 60ch;
}

.about-copy p {
  font-size: 17px;
  line-height: 1.68;
  color: var(--ink-body);
  margin: 0;
}

/* The words are Jerrick's, not the founder's, and the About band opens in
   the founder's first person - so the accent rule stays even now that his
   name sits above the quote: it marks the sentences as his. */
.about-quote {
  margin: 24px 0 0;
  padding-left: 18px;
  border-left: 2px solid var(--accent);
}

.about-quote p {
  font-size: 16px;
  line-height: 1.68;
  color: var(--ink-body);
  margin: 0;
}

/* The studio's second person, in a contained panel beside the founder's copy
   rather than stacked underneath it. Same surface, hairline and radius as the
   other cards on the page (`.plan`, `.care`, `.contact-panel`), so it reads as
   one of this page's objects rather than an imported team card. */
.about-person {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: clamp(22px, 2.6vw, 28px);
  box-shadow: var(--shadow-card);
}

/* The founder's head is a heading that can run to several lines, so it hangs
   from the top of its card. Three short lines beside a 150px portrait sit
   better centred, anchored to the face they belong to. */
.about-person .about-head {
  align-items: center;
}

.about-person-id {
  flex: 1 1 160px;
  min-width: 0;
}

.about-person-name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 21px;
  line-height: 1.2;
  letter-spacing: -0.016em;
  color: var(--ink);
  margin: 0;
}

.about-person-role {
  font-size: 13.5px;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--ink-muted);
  margin: 6px 0 0;
}

/* Where he is, in the page's own voice and in the page's own place idiom -
   the same uppercase micro-label as `.hero-place`. It states the fact and
   stops there; it is not a coverage claim.

   It sits on the card's full measure, under the head rather than inside the
   identity column, because the idiom is a wide-tracked label on a full line:
   at 0.2em this string wants about 205px and the column beside a 120px
   portrait offers 167px, so it broke inside the place name. Keeping the
   treatment and giving it the measure beats shrinking the type to fit. */
.about-person-place {
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin: 18px 0 0;
}

.contact {
  scroll-margin-top: 88px;
}

.contact-panel {
  margin-top: clamp(28px, 3.5vw, 40px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: clamp(22px, 3vw, 32px);
  box-shadow: var(--shadow-panel);
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* On a full-width band the column would stretch the button to the whole
   measure, which reads as a slab rather than an action. It sizes to its
   label instead, like the hero buttons. */
.contact-form .btn {
  align-self: flex-start;
  min-width: 160px;
}

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 18px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}

.field label {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-body);
}

.field input,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--field);
  /* 16px keeps iOS from zooming the viewport on focus. */
  font-size: 16px;
  line-height: 1.6;
  transition: border-color 160ms ease-out;
}

.field input {
  min-height: 48px;
}

.field textarea {
  resize: vertical;
}

.field input:hover,
.field textarea:hover {
  border-color: var(--line-strong);
}

.field ::placeholder {
  color: var(--ink-muted);
  opacity: 1;
}

.form-note {
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink-muted);
  margin: 0;
  border-top: 1px solid var(--line);
  padding-top: 16px;
}

.form-status {
  font-size: 15px;
  line-height: 1.6;
  color: var(--evergreen);
  margin: 0;
  border-top: 1px solid var(--line);
  padding-top: 16px;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  border-top: 1px solid var(--line);
}

.site-footer > .shell {
  padding-block: 32px 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
}

.site-footer p {
  font-size: 14px;
  color: var(--ink-muted);
  margin: 0;
}

.footer-links {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  font-size: 14.5px;
}

.footer-sep {
  color: var(--line);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1000px) {
  .hero-inner,
  .about-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  .work-grid,
  .plan-grid,
  .steps {
    grid-template-columns: minmax(0, 1fr);
  }

  /* One card per row: there is no neighbouring card to hold a baseline
     against, so the reserved height would only be slack. */
  .plan-for {
    min-height: 0;
  }

  /* Stacked under the bio rather than beside it. Left as a contained card at
     a readable measure, not stretched across the band - the quote is four
     sentences and would otherwise run the full width in single lines. */
  .about-person {
    max-width: 620px;
  }

  .step + .step {
    border-left: 0;
    border-top: 1px solid var(--line);
  }
}

@media (max-width: 760px) {
  /* No hamburger by design: this is a single scrolling page and the one
     action worth keeping in the bar is "Start a project". */
  .site-nav {
    display: none;
  }

  .hero-buttons {
    flex-direction: column;
    align-items: stretch;
  }

  /* Full-width tap target on a phone. */
  .contact-form .btn {
    align-self: stretch;
  }

  /* The mock keeps its structure at phone width but drops the text bars,
     which would otherwise be sub-pixel noise. */
  .morph-url,
  .morph-tile .morph-bar {
    display: none;
  }

  .hero-morph[data-morph-mobile='hidden'] {
    display: none;
  }
}

/* Below the width where the longest hero term still fits its column, an
   atomic term would run past the column instead of wrapping. Here, and only
   here, a term is allowed to break inside itself. Each one is still a block
   that starts on its own line, so the rule the terms are set by survives:
   the line breaks between terms, except in the single term too wide to fit
   at all.

   334px is measured, not chosen: the longest term is 294.34px, the terms
   column is the viewport less 40px of gutters, so the term needs a viewport
   of 334.34px. It clears at 335 and overhangs at 334. Rounding this up to a
   tidier 360 or 380 would wrap phones that do not need to wrap; rounding it
   down brings the overhang back. Re-measure it if the terms change. */
@media (max-width: 334px) {
  .hero-terms span {
    display: inline-block;
    white-space: normal;
  }
}
