/* ==========================================================================
   Small House Studio — homepage
   Full redesign per Claude Design's build spec (shs-home-build/BUILD-INSTRUCTIONS.md).
   Fonts loaded via Google Fonts <link> in index.html <head>.
   ========================================================================== */

:root {
  --ink: #2E2620;
  --ink-soft: #4A4034;
  --ink-mute: #8A8571;
  --caption: #6B6455;
  --paper: #FCF8EE;
  --oat: #EFE6D6;
  --rule: #DDD3BC;
  --rule-soft: #E4DBC6;
  --green: #3F5138;
  --green-line: #55684C;
  --green-label: #AFBCA4;
  --green-body: #C4CFB9;
  --sage: #9EAA92;
  --terracotta: #B96A5E;
  --apricot: #E8B9A6;
  --cream-on-green: #F1EEE2;

  /* Caps how wide content gets on large monitors. Color bands still bleed
     edge to edge; only what's inside them is constrained. */
  --content-width: 1200px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Newsreader', Georgia, serif;
  font-weight: 500;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: var(--green); text-decoration: none; }
a:hover, a:focus-visible { color: var(--terracotta); }
a:focus-visible, button:focus-visible, input:focus-visible {
  outline: 2px solid var(--terracotta);
  outline-offset: 2px;
}

h1, h2, h3, p { margin: 0; }

/* ---------- Page frame ----------
   The whole site is one enclosed sheet on the oat ground. Sections butt
   directly against each other and are separated by hairlines, not gaps,
   so the page reads as a single composed document. */

.page-frame {
  max-width: var(--content-width);
  margin: 0 auto;
  background: var(--paper);
}

/* The darker mat only reads as a mat when the sheet is inset on every
   side. Below the content width plus a gutter the frame already fills the
   viewport, so those vertical margins have nothing to their left or right
   and show up as unexplained bands above the header and below the footer
   -- which is exactly how they looked on an iPad. So the mat, the margins
   and the outer border all arrive together, or not at all. */
@media (min-width: 1292px) {
  body { background: var(--rule); }

  .page-frame {
    margin: 40px auto 44px;
    border: 1px solid var(--rule);
  }
}

.page-frame > * + * {
  border-top: 1px solid var(--rule);
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: 64px;
  padding: 0 28px;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: center;
  justify-content: center;
}

.site-header-mark img { height: 22px; width: auto; display: block; }

@media (max-width: 720px) {
  .site-header { height: 56px; padding: 0 16px; }
  .site-header-mark img { height: 18px; }
}

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

.hero {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--paper);
}

.hero-copy { padding: 40px 44px; display: flex; flex-direction: column; justify-content: center; }

.hero-eyebrow {
  font-family: 'League Spartan', sans-serif;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--terracotta);
}

.hero-copy h1 {
  font-family: 'League Spartan', sans-serif;
  font-weight: 800;
  font-size: 46px;
  letter-spacing: -0.018em;
  line-height: 1;
  color: var(--ink);
  margin-top: 18px;
}

.hero-lede {
  font-family: 'Newsreader', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 22px;
  line-height: 1.4;
  color: var(--green);
  max-width: 17em;
  margin-top: 20px;
}

/* Substack's embed renders a terms line under the field that we can't
   remove or restyle (cross-origin), and it centers its content vertically
   inside the iframe. So shrinking the iframe crops from both ends and
   leaves you looking at the middle. Instead: keep the iframe at its
   natural height so the widget lays out normally, then pull it up inside
   a short window so the field sits at the top and everything below it is
   clipped.

   --embed-offset: how far down the field starts inside the iframe.
   --embed-visible: how much of it to show.
   These two numbers are the whole mechanism -- if Substack changes the
   widget's layout, retune them and nothing else. */
.hero-signup {
  --embed-offset: 20px;
  --embed-visible: 56px;
  /* The widget carries a few px of its own padding, which left its box
     looking inset from the text above it and pushed its right edge up
     against the frame. Shifting left by that padding fixes both at once. */
  --embed-nudge-left: 5px;
  max-width: 24em;
  margin-top: 26px;
  height: var(--embed-visible);
  overflow: hidden;
}

.hero-signup iframe {
  display: block;
  width: calc(100% + var(--embed-nudge-left));
  height: 150px;
  border: 0;
  background: transparent;
  margin-top: calc(-1 * var(--embed-offset));
  margin-left: calc(-1 * var(--embed-nudge-left));
}

/* The widget is capped at 24em (384px), so the terms text only re-wraps
   once the container can no longer give it that -- below 384 + 88px of
   hero padding = 472px. Not at any of the layout's other breakpoints.
   Below it the terms run to three lines and Substack adds its wordmark,
   so the content is taller and, being centered, starts higher -- hence a
   much smaller offset. */
@media (max-width: 471px) {
  .hero-signup {
    --embed-offset: 4px;
    --embed-visible: 58px;
  }

  /* The widget draws its box flush to the iframe's edges, and the window
     clips at exactly the same place, so the right border lands on the clip
     boundary and gets shaved. Pulling the iframe in gives it slack. */
  .hero-signup iframe {
    width: calc(100% - var(--embed-nudge-left));
  }
}

.hero-fine-print {
  font-family: 'League Spartan', sans-serif;
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 11px;
}

.hero-photo {
  position: relative;
  min-height: 430px;
  overflow: hidden;
}

.hero-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
}

@media (max-width: 800px) {
  .hero { grid-template-columns: 1fr; }
  .hero-photo { aspect-ratio: 4 / 3; min-height: 0; }
}

/* ---------- Green strip: Also at the studio ---------- */

.also-strip {
  background: var(--green);
  color: var(--cream-on-green);
}

.also-strip-inner {
  display: grid;
  grid-template-columns: 150px 1fr 1fr 1fr;
}

.also-label {
  padding: 20px 0 20px 24px;
  display: flex;
  align-items: center;
  font-family: 'League Spartan', sans-serif;
  font-weight: 600;
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--green-label);
  line-height: 1.5;
}

.also-offer {
  border-left: 1px solid var(--green-line);
  padding: 20px 24px;
}

.also-offer-title {
  font-family: 'Newsreader', serif;
  font-size: 19px;
  color: var(--cream-on-green);
}

.also-offer-sub {
  font-family: 'Newsreader', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 14.5px;
  line-height: 1.4;
  color: var(--green-body);
  margin-top: 4px;
}

@media (max-width: 800px) {
  .also-strip-inner { grid-template-columns: 1fr; }
  .also-label { padding: 20px 24px 8px; }
  .also-offer { border-left: none; border-top: 1px solid var(--green-line); }
}

/* ---------- Pull quote ---------- */

.pull-quote {
  background: var(--oat);
  padding: 52px 56px 46px;
  text-align: center;
}

.pull-quote p {
  font-family: 'Newsreader', serif;
  font-weight: 500;
  font-size: 24px;
  line-height: 1.55;
  max-width: 26em;
  margin: 0 auto;
  color: var(--ink);
}

.pull-quote em {
  font-style: italic;
  color: var(--green);
}

/* ---------- The Afternoon ---------- */

.afternoon-section {
  background: var(--paper);
}

.afternoon-card {
  padding: 38px 56px;
}

.section-label {
  font-family: 'League Spartan', sans-serif;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--terracotta);
  margin-bottom: 26px;
}

.afternoon-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
}

.afternoon-cols > div:nth-child(2),
.afternoon-cols > div:nth-child(3) {
  border-left: 1px solid var(--rule-soft);
  padding-left: 30px;
}

.afternoon-cols h3 {
  font-family: 'League Spartan', sans-serif;
  font-weight: 700;
  font-size: 26px;
  color: var(--ink);
  margin: 0 0 12px;
}

.afternoon-cols p {
  font-family: 'Newsreader', serif;
  font-weight: 500;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-soft);
}

@media (max-width: 800px) {
  .afternoon-cols { grid-template-columns: 1fr; }
  .afternoon-cols > div:nth-child(2),
  .afternoon-cols > div:nth-child(3) {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--rule-soft);
    padding-top: 24px;
  }
}

/* ---------- Aerial band ---------- */

.aerial-band {
  background: var(--paper);
}

.aerial-band img { display: block; width: 100%; height: auto; }

.aerial-caption {
  padding: 12px 56px 20px;
  font-family: 'League Spartan', sans-serif;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--caption);
}

/* ---------- The Studio ---------- */

.studio-section {
  padding: 34px 56px 40px;
  background: var(--oat);
}

.studio-header {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 32px;
  align-items: baseline;
}

.studio-intro {
  font-family: 'Newsreader', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.5;
  color: var(--green);
  max-width: 34em;
}

.studio-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 22px;
}

.studio-tile-frame {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.studio-tile-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.studio-caption {
  font-family: 'League Spartan', sans-serif;
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-top: 9px;
}

@media (max-width: 720px) {
  .studio-gallery { grid-template-columns: 1fr; }
}

/* ---------- Signup band ---------- */

.signup-band {
  background: var(--green);
  color: var(--cream-on-green);
}

.signup-band-inner {
  padding: 40px 56px;
  display: grid;
  /* The widget column gives ground first, so the headline never gets
     squeezed into a 267px ribbon just above the stacking breakpoint
     (iPad portrait sits right in that range). The 340px floor keeps the
     iframe inside the width range the offsets above were measured at --
     narrower than that and the terms line rewraps taller, which lifts the
     whole widget and can bring the terms into the window. */
  grid-template-columns: minmax(0, 1fr) clamp(340px, 35%, 380px);
  gap: 40px;
  align-items: center;
}

.signup-band h2 {
  font-family: 'League Spartan', sans-serif;
  font-weight: 700;
  font-size: 28px;
  line-height: 1.12;
  margin-bottom: 10px;
  color: var(--cream-on-green);
}

.signup-band p {
  font-family: 'Newsreader', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.5;
  color: #CFD6C6;
}

/* The widget is vertically centred inside its iframe, so we give the
   iframe its natural height and slide it up inside a window.

   The numbers below are measured off screenshots of the live embed at
   both sizes, not guessed. In the iframe's own coordinates the widget's
   visible box sits at y 24.5 on desktop and 23.5 on phones, is 41px
   tall, and the terms line beneath it starts no earlier than y 76. A
   window of 14..70 therefore clears the box with roughly even padding at
   every width and never lets the terms line peek in -- which is why this
   needs no breakpoint of its own. Horizontally the widget keeps ~15px of
   its own padding inside the iframe, and that serves as the card's side
   padding. */
.signup-embed {
  --embed-offset: 14px;
  --embed-visible: 56px;
  background: var(--paper);
  border-radius: 8px;
  max-width: 380px;
  height: var(--embed-visible);
  overflow: hidden;
}

.signup-embed iframe {
  display: block;
  width: 100%;
  height: 150px;
  border: 0;
  background: transparent;
  margin-top: calc(-1 * var(--embed-offset));
}

@media (max-width: 800px) {
  .signup-band-inner { grid-template-columns: 1fr; gap: 26px; padding: 34px 26px; }
}

/* ---------- Host paragraph ---------- */

.host-section {
  padding: 38px 56px 32px;
  background: var(--oat);
  display: flex;
  align-items: center;
  gap: 32px;
}

.host-section p {
  flex: 1 1 auto;
  min-width: 0;
  font-family: 'Newsreader', serif;
  font-weight: 500;
  font-size: 19px;
  line-height: 1.55;
  max-width: 42em;
  color: var(--ink);
}

.host-section em { font-style: italic; }

.host-photo-frame {
  flex: 0 0 auto;
}

.host-photo-frame img {
  height: 100px;
  width: auto;
  display: block;
}

@media (max-width: 720px) {
  .host-section {
    flex-direction: column;
    align-items: center;
  }
  .host-photo-frame {
    order: -1;
  }
  .host-photo-frame img {
    height: auto;
    width: 100%;
    max-width: 320px;
  }
}

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

.site-footer {
  padding: 26px 56px 34px;
  background: var(--paper);
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: space-between;
  align-items: flex-end;
}

.footer-mark {
  font-family: 'League Spartan', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--ink);
}

.footer-meta {
  text-align: right;
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-family: 'League Spartan', sans-serif;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.footer-meta a[href^="mailto"] { color: var(--ink); }
.footer-meta a.footer-instagram { color: var(--terracotta); }
.footer-meta .footer-location { color: var(--ink-mute); }
