/* ==========================================================================
   Ruth's BBQ Sauce
   Built to the measured geometry of the approved "Bold Pitmaster" design.
   Deviations from the design are limited to documented contrast fixes (§6 of
   design-fidelity-standards) and to surfaces the design does not define at all
   (mobile, states, /thank-you, 404). Both are marked DEVIATION / UNDESIGNED.
   ========================================================================== */

/* ---------- Fonts (self-hosted, latin subset, matching the faces the
     design's Google Fonts @import actually loaded) ------------------------ */
@font-face{font-family:'Anton';font-style:normal;font-weight:400;font-display:swap;
  src:url('../fonts/anton-400.woff2') format('woff2')}
@font-face{font-family:'Lora';font-style:normal;font-weight:400;font-display:swap;
  src:url('../fonts/lora-400.woff2') format('woff2')}
@font-face{font-family:'Lora';font-style:italic;font-weight:400;font-display:swap;
  src:url('../fonts/lora-400i.woff2') format('woff2')}
@font-face{font-family:'Nunito Sans';font-style:normal;font-weight:700;font-display:swap;
  src:url('../fonts/nunitosans-700.woff2') format('woff2')}
@font-face{font-family:'Nunito Sans';font-style:normal;font-weight:800;font-display:swap;
  src:url('../fonts/nunitosans-800.woff2') format('woff2')}

/* Lora 700 is deliberately NOT loaded. The design's @import requested only
   400/500/italic, so its bold nutrition labels rendered as synthesised bold.
   Loading a real 700 here would make the build heavier AND differ from the
   approved design. */

/* ---------- Tokens ------------------------------------------------------ */
:root{
  --char:#16110E;
  --bone:#F3EDE3;
  --ruths-red:#C0242C;
  --ruths-red-hover:#9E1B24;
  --ember:#C75B24;
  --ash:#574B41;

  --surface-dark-2:#1F1915;
  --border-dark:#2C241E;
  --muted-on-dark:#C9BFB3;
  --muted-on-light:#6E635A;
  --divider-light:#E3DBCE;

  /* DEVIATION (contrast, design-fidelity-standards §6). The design used one
     --ember #C75B24 on both grounds. Measured 4.42:1 on Char and 3.64:1 on
     Bone; AA needs 4.5:1 for 21px non-bold text. Minimum lightness change
     only, hue and chroma untouched. Ember is unchanged anywhere it passes. */
  --ember-on-dark:#D16026;   /* was #C75B24 — 4.42:1 -> 4.83:1, +2.3% L */
  --ember-on-light:#A84D1E;  /* was #C75B24 — 3.64:1 -> 4.82:1, -7.1% L */

  /* DEVIATION (contrast). The design used --ash for text on Char in two
     places — the footer copyright and the form hint — both at 2.22:1.
     --ash itself is untouched; this is the value used when it carries text. */
  --ash-on-dark:#927E6D;     /* 2.22:1 -> 4.84:1 */

  --space-1:4px;  --space-2:8px;  --space-3:12px; --space-4:16px; --space-5:24px;
  --space-6:32px; --space-7:48px; --space-8:64px; --space-9:96px; --space-10:128px;

  --content-max:1100px;      /* measured: a PIXEL container, not a percentage */
  --radius-badge:3px;

  --font-display:'Anton',Impact,sans-serif;
  --font-body:'Lora',Georgia,serif;
  --font-ui:'Nunito Sans',system-ui,sans-serif;

  --section-pad-y:96px;
  --section-pad-x:64px;
  --hero-pad-top:180px;

  /* The design's crosshatch is a gradient, not an image asset. */
  --hatch-dark:repeating-linear-gradient(-45deg,rgba(243,237,227,.04) 0,rgba(243,237,227,.04) 2px,transparent 2px,transparent 16px);
  --hatch-light:repeating-linear-gradient(-45deg,rgba(22,17,14,.021) 0,rgba(22,17,14,.021) 2px,transparent 2px,transparent 14px);
}

/* ---------- Base -------------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--char);color:var(--bone);
  font-family:var(--font-body);font-size:17px;line-height:1.62;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
::selection{background:var(--ruths-red);color:var(--bone)}

/* UNDESIGNED: the design has no focus states at all. Must be visible on
   Char, Bone and Red grounds, so the ring is drawn in the opposite value
   with an offset that reads on any of the three. */
:where(a,button,input,textarea,select,summary):focus-visible{
  outline:3px solid var(--bone);
  outline-offset:2px;
}
.ground-light :where(a,button,input,textarea,select):focus-visible,
.ground-red   :where(a,button,input,textarea,select):focus-visible{
  outline-color:var(--char);
}

.skip-link{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--ruths-red);color:var(--bone);
  font-family:var(--font-ui);font-weight:700;font-size:14px;padding:12px 24px;
}
.skip-link:focus{left:0}

/* ---------- Layout ------------------------------------------------------ */
.container{max-width:var(--content-max);margin:0 auto}

.section{padding:var(--section-pad-y) var(--section-pad-x)}
/* Contact and /thank-you open on a lede section rather than a photo hero, but
   carry the hero's top padding so the overhanging nav logo clears. */
.section-lede{padding:var(--hero-pad-top) var(--section-pad-x) 96px}
.ground-dark{background:var(--char);background-image:var(--hatch-dark)}
.ground-dark-plain{background:var(--char)}
.ground-hatch{background-image:var(--hatch-dark)} /* hatch over the body char */
.ground-light{background:var(--bone);background-image:var(--hatch-light);color:var(--char)}
.ground-red{background:var(--ruths-red);color:var(--bone)}

/* ---------- Type roles -------------------------------------------------- */
.display{
  font-family:var(--font-display);font-weight:400;line-height:1.05;
  letter-spacing:.5px;text-transform:uppercase;color:var(--bone);margin:0;
  /* Even out heading line lengths instead of letting a word strand on its
     own line. Matters most at 360, where a 56px display face wraps hard. */
  text-wrap:balance;
}
/* Body copy: `pretty` specifically prevents a single-word last line. Several
   text blocks here are div/span rather than p/li — the footer copyright,
   reviewer names, badges, the facts rows — so they have to be named, or they
   keep stranding words while the paragraphs behave. */
p,li,
.site-footer__legal,.site-footer__tagline,
.review__name,.badge,
.facts__note,.facts__serving,.nrow,.field__hint,
.contact-list div{text-wrap:pretty}
.ground-light .display{color:var(--char)}
h1.display{font-size:clamp(56px,7vw,96px)}
h2.display{font-size:clamp(36px,4vw,48px)}
h3.display{font-size:28px}
/* The design set the Nutrition panel headings as <h3> directly under the <h1>,
   skipping a level. Heading ORDER is fixed (they are h2 in the build); the
   design's 28px SIZE is preserved exactly via this modifier. */
/* Two classes, so it outranks the h2.display element+class selector above.
   Caught by the geometry diff: it was rendering 48px, not 28px. */
.display.display--sm{font-size:28px}

/* A three-word heading breaking over two lines ALWAYS strands one word —
   balancing cannot help, because either split leaves a line holding one word.
   This scales the phrase to sit on a single line instead. Used only on the
   404, a page the design never covered. */
.display.display--fit{font-size:clamp(34px,11.5vw,96px)}

/* The italic subline sits BELOW its heading and is never an eyebrow above. */
.display-sub{
  font-family:var(--font-body);font-style:italic;font-size:21px;line-height:1.62;
  color:var(--ember-on-dark);margin:16px 0 0;
}
.ground-light .display-sub{color:var(--ember-on-light)}

.heading-group{margin:0}
.heading-group--center{text-align:center}

.prose{font-family:var(--font-body);font-size:18px;line-height:1.62;color:var(--char)}
.prose p{margin:0 0 1.1em}
.prose p:last-child{margin-bottom:0}
.body-dark{font-family:var(--font-body);font-size:17px;line-height:1.6;color:var(--muted-on-dark);margin:0}
.measure{max-width:460px}
.measure-wide{max-width:480px}

.label{
  font-family:var(--font-ui);font-weight:800;font-size:12px;letter-spacing:2px;
  text-transform:uppercase;color:var(--muted-on-dark);
}
.ground-light .label{color:var(--muted-on-light)}

/* Body links. DEVIATION (contrast): the design set link text to --ruths-red,
   which is 3.15:1 on Char and fails AA. Red is kept as the link signifier in
   the underline — 3.15:1 clears the 3:1 bar for non-text UI — and the text
   itself takes the passing value. Red is untouched everywhere it passes. */
.link{
  color:var(--bone);
  /* 17px text is a 22px target. The padding lifts it over 24px and the equal
     negative margin keeps the surrounding layout byte-for-byte where the
     design put it. */
  display:inline-block;padding:3px 0;margin:-3px 0;
  text-decoration:underline;
  text-decoration-color:var(--ruths-red);
  text-decoration-thickness:2px;
  text-underline-offset:4px;
  transition:text-decoration-color .15s ease;
}
.link:hover{text-decoration-color:var(--bone)}
.ground-light .link{color:var(--char)}
.ground-light .link:hover{text-decoration-color:var(--char)}

/* ---------- Buttons ----------------------------------------------------- */
.btn{
  font-family:var(--font-ui);font-weight:700;font-size:14px;line-height:1.2;
  padding:12px 24px;border-radius:0;cursor:pointer;display:inline-block;
  border:1px solid transparent;text-decoration:none;
  transition:background .15s ease,color .15s ease,border-color .15s ease;
}
.btn--primary{background:var(--ruths-red);color:var(--bone)}
.btn--primary:hover{background:var(--ruths-red-hover);color:var(--bone)}
.btn--secondary{background:transparent;color:var(--bone);border-color:var(--bone)}
.btn--secondary:hover{background:rgba(243,237,227,.1);color:var(--bone)}
.ground-light .btn--secondary{color:var(--char);border-color:var(--char)}
.ground-light .btn--secondary:hover{background:rgba(22,17,14,.08)}
/* UNDESIGNED states */
.btn[disabled],.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.btn.is-busy{opacity:.7;cursor:progress}

.btn-row{display:flex;gap:16px;flex-wrap:wrap}

/* ---------- Badge / divider -------------------------------------------- */
.badge{
  font-family:var(--font-ui);font-weight:800;font-size:12px;letter-spacing:2px;
  text-transform:uppercase;padding:4px 10px;border-radius:var(--radius-badge);
  border:1px solid var(--border-dark);background:var(--char);
  color:var(--muted-on-dark);display:inline-block;
}
.ground-light .badge{border-color:var(--divider-light);background:var(--bone);color:var(--muted-on-light)}
.badge-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:28px}

.divider{border:none;border-top:1px solid var(--border-dark);margin:0}
.ground-light .divider{border-top-color:var(--divider-light)}

/* ---------- Pull quote -------------------------------------------------- */
.pullquote{margin:0;border-left:2px solid var(--ruths-red);padding-left:28px}
.pullquote p{
  font-family:var(--font-body);font-style:italic;font-size:26px;line-height:1.4;
  color:var(--bone);margin:0;
}
.ground-light .pullquote p{color:var(--char)}
.pullquote footer{
  font-family:var(--font-ui);font-weight:800;font-size:12px;letter-spacing:2px;
  text-transform:uppercase;color:var(--muted-on-dark);margin-top:16px;
}
.ground-light .pullquote footer{color:var(--muted-on-light)}

/* ---------- Spark bullet list ------------------------------------------ */
.bullets{list-style:none;margin:24px 0 0;padding:0;display:flex;flex-direction:column;gap:14px}
.bullets li{
  display:flex;align-items:baseline;gap:14px;
  font-family:var(--font-body);font-size:17px;line-height:1.5;color:var(--bone);
}
.ground-light .bullets li{color:var(--char)}
.bullets svg{flex-shrink:0;transform:translateY(1px)}

/* ---------- Header / nav ------------------------------------------------ */
.site-header{
  position:relative;background:var(--char);
  border-bottom:1px solid var(--border-dark);height:76px;z-index:10;
}
.nav-logo{
  position:absolute;top:10px;left:50%;transform:translateX(-50%);
  width:177px;height:177px;background:var(--bone);border-radius:50%;
  border:1px solid var(--border-dark);
  display:flex;align-items:center;justify-content:center;z-index:5;
}
.nav-logo img{height:150px;width:auto}
.nav-desktop{display:grid;grid-template-columns:1fr 220px 1fr;height:100%;align-items:center}
.nav-group{display:flex;align-items:center;gap:clamp(14px,2.5vw,32px)}
.nav-group--left{justify-content:flex-end}
.nav-group--right{justify-content:flex-start}
.nav-link{
  font-family:var(--font-ui);font-weight:800;font-size:13px;letter-spacing:2px;
  text-transform:uppercase;white-space:nowrap;text-decoration:none;
  color:var(--muted-on-dark);
  border-bottom:2px solid transparent;padding-bottom:4px;
  transition:color .15s ease;
}
.nav-link:hover{color:var(--bone)}
/* DEVIATION (contrast): the design set the active link's TEXT to --ruths-red
   at 3.15:1. The 2px red underline the design also specified is kept exactly;
   only the text value changes, to Bone at 16.09:1. */
.nav-link[aria-current="page"]{color:var(--bone);border-bottom-color:var(--ruths-red)}

/* UNDESIGNED: no mobile menu exists in the design. Built as a <details>
   disclosure so it needs no JavaScript at all — it works with JS off, is
   keyboard-operable natively, and keeps the CSP free of inline script. */
.nav-mobile-wrap{display:none}
.nav-toggle::-webkit-details-marker{display:none}
.nav-toggle::marker{content:""}

/* ---------- Hero -------------------------------------------------------- */
.hero{position:relative;padding:var(--hero-pad-top) var(--section-pad-x) 96px}
/* The <picture> is positioned, not the <img>, so it does not participate as a
   flex item in .hero--home the way a bare absolute <img> would not. */
.hero picture{position:absolute;inset:0}
/* Full-frame photo + object-position, exactly as the design did it. An earlier
   build pre-cropped each hero to the band the design displayed, which saved
   bytes but drifted the framing off the bottles. */
.hero__media{width:100%;height:100%;object-fit:cover}
/* DEVIATION, requested: the design used 60%, which at 1920x620 shows the
   bottle bases and mostly countertop. 45% centres the band on the bottles
   themselves — caps, shoulders and labels. Verified against the design's own
   crop window (45.5%-69.7% of the source) before changing it. */
.hero--home .hero__media{object-position:center 45%}
.hero--about .hero__media{object-position:50% 46%}
.hero--nutrition .hero__media{object-position:center 42%}
.hero__scrim{position:absolute;inset:0;background:rgba(22,17,14,.82);background-image:var(--hatch-dark)}
.hero__inner{position:relative;max-width:var(--content-max);margin:0 auto}

/* Home's hero is measured differently from every other hero and the
   difference is deliberate: its content block is shrink-to-fit and ranged
   LEFT at x=64, where About/Nutrition/Contact centre a 1100px container at
   x=410. Do not "tidy" these into agreement. */
.hero--home{padding:0;min-height:620px;display:flex;align-items:center}
.hero--home .hero__scrim{background:rgba(22,17,14,.72);background-image:none}
.hero--home .hero__inner{
  padding:var(--hero-pad-top) var(--section-pad-x) 80px;
  width:max-content;max-width:min(1228px,100%);margin:0;
}
.hero--home .btn-row{margin-top:40px}

/* ---------- Section layouts -------------------------------------------- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center}
.split--quote{grid-template-columns:380px 1fr;gap:72px}
.split--story{grid-template-columns:420px 1fr;gap:64px;align-items:start}
.split--wide{gap:80px;align-items:start}

/* height:auto is load-bearing. The width/height attributes needed for CLS map
   to CSS presentational hints, so without it the intrinsic height (1088px)
   beat the 4/3 aspect box and the section rendered 1280px instead of 583px. */
/* Ingredients column: the design's paragraph, then the badges, then the
   cut-out trio filling the space beside the tall facts panel. The photo has a
   transparent ground so it sits on the Bone relief with no white box. */
.ingredients{margin:24px 0 32px}
.trio-cutout{width:100%;height:auto;max-width:440px;margin:44px auto 0;display:block}

.framed{border:1px solid var(--divider-light);width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;object-position:center 38%}

/* Ruth's portrait sits in a lot of flat ground on both pages, so it gets an
   offset accent block behind it. Built from devices the design already uses:
   a flat Ruth's Red rectangle, square corners, no shadow, 1px border. Red
   reads against Char and Bone, so the same treatment works on both pages. */
.photo-offset{position:relative;display:block}
.photo-offset::before{
  content:"";position:absolute;left:-18px;bottom:-18px;width:100%;height:100%;
  background:var(--ruths-red);z-index:0;
}
.photo-offset > *{position:relative;z-index:1}

/* Ruth portraits are native ~4:5, so they fill the frame with no zoom. */
.crop{overflow:hidden;aspect-ratio:4/5}
.crop--bordered{border:1px solid var(--border-dark)}
.crop img{
  width:100%;height:100%;object-fit:cover;object-position:center;
}

/* ---------- Red CTA band ------------------------------------------------ */
.cta-band{padding:88px var(--section-pad-x);text-align:center;position:relative;overflow:hidden}
.cta-band__mark{
  position:absolute;right:-70px;top:50%;transform:translateY(-50%) rotate(-12deg);
  width:380px;height:auto;opacity:.1;filter:brightness(0) invert(1);pointer-events:none;
}
/* Bottle watermark balancing the logo mark on the opposite side. Same white,
   same opacity, tilted the other way so the pair reads as a set. */
/* The client's own cut-out bottle, kept as a PHOTOGRAPH rather than knocked
   back to a white profile — no filter. Scaled well past the band height so it
   crops top and bottom: the fluted shoulder and label read at this zoom,
   where the whole bottle at band height read as a small object. Opacity is
   the only thing holding it back, so it stays a watermark rather than
   becoming a background image. */
.cta-band__bottle{
  position:absolute;left:56px;top:50%;transform:translateY(-50%) rotate(-9deg);
  height:620px;width:auto;opacity:.32;pointer-events:none;
}
/* On a 360px band there is no clear space to the left, so the same zoom and
   opacity puts the label straight behind the CTA button. Pulled back and
   pushed off the edge so it stays texture, not competition. */
@media (max-width:900px){
  .cta-band__bottle{left:-88px;height:330px;opacity:.13}
}
.cta-band__inner{position:relative}
/* DEVIATION (contrast): the design set this lede to Bone at 90% opacity,
   which composites to 4.39:1 on Red. Removing the opacity is the smallest
   possible change and restores 5.11:1. */
.cta-band__lede{
  font-family:var(--font-body);font-style:italic;font-size:21px;
  color:var(--bone);margin:16px auto 0;max-width:520px;
}
.cta-band .btn-row{justify-content:center;margin-top:36px}

/* ---------- Testimonials ------------------------------------------------ */
.testimonials{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin-top:56px}
.review{
  background:var(--bone);padding:28px 28px 32px;
  display:flex;flex-direction:column;gap:14px;
  /* Faint logo mark bled off the bottom-right corner, echoing the watermark
     treatment in the red band. Kept under 8% so it never fights the quote. */
  position:relative;overflow:hidden;
  /* §4 worst-case content: the real reviews run 18 to 52 words. Equal-height
     cards keep the 3x2 grid from going ragged; the design's own content was
     length-matched and never showed this. */
  height:100%;
}
.review::after{
  content:"";position:absolute;right:-26px;bottom:-26px;width:140px;height:123px;
  background:url("../img/logo-340.webp") no-repeat center/contain;
  opacity:.07;pointer-events:none;
}
.review__head{display:flex;align-items:center;gap:14px;position:relative}
.review__text{position:relative}
.review__avatar{
  width:44px;height:44px;border-radius:50%;background:var(--ruths-red);color:var(--bone);
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-ui);font-weight:800;font-size:16px;flex-shrink:0;
}
.review__name{font-family:var(--font-ui);font-weight:800;font-size:15px;color:var(--char)}
.review__stars{color:var(--ruths-red);font-size:14px;letter-spacing:2px}
.review__text{
  margin:0;font-family:var(--font-body);font-size:15.5px;line-height:1.55;color:var(--char);
}

/* ---------- Contact ----------------------------------------------------- */
.contact-list{display:flex;flex-direction:column;gap:20px;font-family:var(--font-body);font-size:17px}
.contact-list .label{display:block;margin-bottom:6px}
.contact-list a,.contact-list span:not(.label){color:var(--bone)}

/* ---------- Forms ------------------------------------------------------- */
.field{display:flex;flex-direction:column;gap:8px}
.field__hint{font-family:var(--font-body);font-style:italic;font-size:14px;color:var(--ash-on-dark)}
.input,.textarea,.select{
  font-family:var(--font-body);font-size:16px;padding:12px 14px;border-radius:0;
  width:100%;box-sizing:border-box;outline:none;
  background:#fff;color:var(--char);border:1px solid var(--divider-light);
  transition:border-color .15s ease;
}
.textarea{resize:vertical;line-height:1.5}
.select{cursor:pointer}
.input:focus,.textarea:focus,.select:focus{border-color:var(--ruths-red)}
.form{display:flex;flex-direction:column;gap:24px}
.checkbox{
  display:flex;align-items:center;gap:10px;cursor:pointer;
  font-family:var(--font-ui);font-weight:700;font-size:14px;color:var(--bone);
}
.checkbox input{width:18px;height:18px;accent-color:var(--ruths-red);cursor:pointer}
/* Purchase inquiry is now a required Yes/No below the message. */
fieldset.field{border:0;margin:0;padding:0;min-width:0}
fieldset.field > legend{padding:0;margin-bottom:8px}
.radio-group{display:flex;gap:28px;flex-wrap:wrap}
.radio{
  display:flex;align-items:center;gap:9px;cursor:pointer;min-height:24px;
  font-family:var(--font-ui);font-weight:700;font-size:14px;color:var(--bone);
}
.radio input{width:18px;height:18px;accent-color:var(--ruths-red);cursor:pointer}

/* The quantity field appears only when "Yes" is chosen — :has(), not JS.
   NOTE: the design marked this select `required` while conditionally
   unmounting it. As plain HTML that is a defect: a hidden required control
   blocks submission with an error the browser cannot surface. Left optional. */
.field--qty{display:none}
.form:has(#purchase-yes:checked) .field--qty{display:flex}
/* UNDESIGNED: the design drew resting + focus only. */
.field__error{
  font-family:var(--font-ui);font-weight:700;font-size:13px;color:#F2A0A5;
  display:none;
}
.field.is-invalid .field__error{display:block}
.field.is-invalid .input,.field.is-invalid .textarea,.field.is-invalid .select{
  border-color:#F2A0A5;border-width:2px;
}
.panel{border:1px solid var(--border-dark);padding:48px;text-align:center}
.panel .display-sub{color:var(--muted-on-dark);font-size:18px}
.panel .btn{margin-top:24px}

/* ---------- Nutrition panel -------------------------------------------- */
.facts{border-top:4px solid var(--char)}
.facts__calories{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0}
.facts__calories span:first-child{font-family:var(--font-display);font-size:28px;text-transform:uppercase;color:var(--char)}
.facts__calories span:last-child{font-family:var(--font-display);font-size:40px;color:var(--char)}
.nrow{
  display:flex;justify-content:space-between;padding:8px 0;
  border-top:1px solid var(--divider-light);
  font-family:var(--font-body);font-size:16px;color:var(--char);
}
.nrow--indent{padding-left:20px}
.nrow__dv{font-family:var(--font-ui);font-weight:700;font-size:14px}
.facts__note{
  border-top:4px solid var(--char);padding-top:10px;
  font-family:var(--font-body);font-style:italic;font-size:14px;color:var(--muted-on-light);
}
.facts__serving{font-family:var(--font-body);font-style:italic;font-size:16px;color:var(--muted-on-light);margin:12px 0 24px}

/* ---------- Footer ------------------------------------------------------ */
.site-footer{background:var(--char);border-top:1px solid var(--border-dark);padding:48px 40px 32px}
.site-footer__top{display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:24px}
.site-footer__brand{display:flex;flex-direction:column;gap:12px}
.footer-logo{
  background:var(--bone);border-radius:50%;width:76px;height:76px;
  display:flex;align-items:center;justify-content:center;
}
.footer-logo img{height:66px;width:auto}
.site-footer__tagline{font-family:var(--font-body);font-style:italic;font-size:15px;color:var(--muted-on-dark)}
/* The design's footer links are 19px tall with a 10px gap — a 19px tap
   target. Padding raises it to 27px and the gap drops by the same 8px, so the
   baseline-to-baseline pitch stays exactly 29px and nothing moves. */
.site-footer nav{display:flex;flex-direction:column;gap:2px}
.site-footer nav a{
  font-family:var(--font-ui);font-weight:800;font-size:12px;letter-spacing:2px;
  text-transform:uppercase;color:var(--muted-on-dark);text-decoration:none;
  transition:color .15s ease;padding:4px 0;
}
.site-footer nav a:hover{color:var(--bone)}
.site-footer__legal{
  border-top:1px solid var(--border-dark);margin-top:32px;padding-top:16px;
  font-family:var(--font-ui);font-size:12px;color:var(--ash-on-dark);
}

/* ---------- One-off layout classes --------------------------------------
   These replace the handful of inline style="" attributes the build started
   with. Every inline style forces style-src 'unsafe-inline' in the CSP, which
   is most of what a CSP is for; eight named classes buy a strict policy.
   They sit at the end of the base layer deliberately: several override a
   component default (.divider, .pullquote, .container) declared above. */
.text-center{text-align:center}
.stack-center{justify-content:center;margin-top:40px}
.pullquote--inset{margin:40px 0}
.divider--spaced{margin:48px 0}
.btn--start{align-self:flex-start}
.prose--under-heading{margin:24px 0 0}
.body-dark--under-quote{margin-top:28px}
.panel-wrap{max-width:720px}

/* ==========================================================================
   UNDESIGNED SURFACE — responsive.
   The design defines exactly one viewport. Measured at 360px it has
   horizontalScroll:true, no grid collapses and the nav logo overflows.
   Everything below is derived from the design's own tokens: section order,
   type roles and rhythm are preserved; only the axis changes.
   ========================================================================== */

@media (max-width:1180px){
  :root{--section-pad-x:40px}
}

@media (max-width:900px){
  :root{--section-pad-y:64px;--section-pad-x:24px;--hero-pad-top:132px}

  /* Nav: the 177px logo circle is the brand device and cannot become a plain
     bar, so it shrinks and the links move into a panel beneath it. */
  .nav-desktop{display:none}
  .nav-logo{width:120px;height:120px;top:8px}
  .nav-logo img{height:100px}
  .nav-mobile-wrap{display:block}
  .nav-toggle{
    display:flex;align-items:center;justify-content:center;
    position:absolute;right:12px;top:16px;
    width:44px;height:44px;background:none;border:1px solid var(--border-dark);
    cursor:pointer;padding:0;list-style:none;z-index:25;
  }
  .nav-toggle span{position:relative;display:block;width:20px;height:2px;background:var(--bone)}
  .nav-toggle span::before,.nav-toggle span::after{
    content:"";position:absolute;left:0;width:20px;height:2px;background:var(--bone);
  }
  .nav-toggle span::before{top:-6px}
  .nav-toggle span::after{top:6px}
  .nav-mobile-wrap[open] .nav-toggle span{background:transparent}
  .nav-mobile-wrap[open] .nav-toggle span::before{top:0;transform:rotate(45deg)}
  .nav-mobile-wrap[open] .nav-toggle span::after{top:0;transform:rotate(-45deg)}

  /* Full-screen overlay, not a dropdown. Anchored below the bar it sliced the
     overhanging logo circle in half, which reads as a rendering fault. */
  .nav-mobile{
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    position:fixed;inset:0;z-index:20;
    background:var(--char);background-image:var(--hatch-dark);
    padding:140px 24px 48px;overflow-y:auto;
    /* Stop a scroll gesture that reaches the overlay's end from chaining
       through to the page behind it. */
    overscroll-behavior:contain;
  }
  /* Lock the page while the overlay is up — still no JavaScript. Scoped to
     mobile, so the desktop nav is untouched, and :has() keeps it tied to the
     <details> open state rather than needing a class toggled by script. */
  html:has(.nav-mobile-wrap[open]),
  html:has(.nav-mobile-wrap[open]) body{overflow:hidden}
  /* Sized to fill the overlay. At 15px the group left a ~170px void under the
     logo and read as an afterthought; 17px with roomier rows closes the gap
     from both ends without inventing a type role — same family, weight,
     tracking and case as the design's nav link. */
  .nav-mobile a{
    display:block;width:100%;max-width:320px;text-align:center;
    padding:18px 0;min-height:52px;
    font-family:var(--font-ui);font-weight:800;font-size:17px;letter-spacing:2px;
    text-transform:uppercase;color:var(--muted-on-dark);text-decoration:none;
  }
  /* Active state keeps the design's red rule, centred under the label rather
     than run full-bleed across a centred row. */
  .nav-mobile a[aria-current="page"]{color:var(--bone)}
  .nav-mobile a[aria-current="page"]::after{
    content:"";display:block;width:44px;height:2px;
    background:var(--ruths-red);margin:9px auto 0;
  }
  .nav-mobile .btn{margin-top:32px;width:100%;max-width:320px;text-align:center;font-size:15px}

  /* While the overlay is up, the logo and the close control must travel with
     it. Both live in the (non-sticky) header, so if the page is scrolled at
     all they would otherwise sit off-screen — leaving no visible way out. */
  .site-header:has(.nav-mobile-wrap[open]) .nav-logo{position:fixed;z-index:22}
  .nav-mobile-wrap[open] .nav-toggle{position:fixed}

  /* One column, section order preserved. */
  .split,.split--quote,.split--story,.split--wide{grid-template-columns:1fr;gap:40px}
  .facts-only{grid-template-columns:1fr}
  .photo-offset::before{left:-12px;bottom:-12px}
  .testimonials{grid-template-columns:1fr;gap:16px;margin-top:40px}
  .split--quote .crop,.split--story .crop{max-width:320px}

  .hero,.section-lede{padding:var(--hero-pad-top) var(--section-pad-x) 64px}
  /* padding:0 must be restated here: the .hero rule above has equal
     specificity and comes later, so it was re-applying the section padding on
     top of .hero__inner's own and pushing the H1 down by a second 132px. */
  .hero--home{min-height:0;display:block;padding:0}
  .hero--home .hero__inner{
    width:auto;max-width:100%;
    padding:var(--hero-pad-top) var(--section-pad-x) 64px;
  }
  .hero--home .btn-row{margin-top:32px}
  /* The design's forced break sits between the two sentences, which is a
     desktop device. At 360 it pins "SAUCE." alone on its own line; dropping
     it lets all eight words balance across four even lines instead. */
  .hero--home h1.display br{display:none}
  .btn-row .btn{flex:1 1 auto;text-align:center}

  .cta-band{padding:64px var(--section-pad-x)}
  .cta-band__mark{width:260px;right:-90px}

  .pullquote{padding-left:20px}
  .pullquote p{font-size:22px}

  .site-footer{padding:40px 24px 28px}
  .site-footer__top{gap:32px}
}

@media (max-width:420px){
  .display-sub{font-size:19px}
  .panel{padding:32px 20px}
}

/* Inputs must stay >=16px so iOS Safari does not zoom on focus. */
@media (max-width:900px){
  .input,.textarea,.select{font-size:16px}
}

@media (prefers-reduced-motion:reduce){
  *{transition-duration:.01ms !important;animation-duration:.01ms !important}
}
