/*
 * The public site.
 *
 * 🔴 **KETTLE, 2026-08-03. THE SITE IS DARK BECAUSE THE APP IS DARK.** Every
 * value below is lifted from `theme/colors.ts` and nothing here is invented. A
 * landing page has one job, which is to look like the thing it is selling, and
 * on 2026-08-03 the app stopped being cream.
 *
 * 🔴 **THE VARIABLES WERE RENAMED, AND THAT IS THE POINT OF THIS COMMIT.** They
 * used to be `--cream`, `--paper`, `--sand`, `--ink`. Pointing `--cream` at
 * `#100C0A` would have worked and would have been a trap: a name that says cream
 * and holds near-black is exactly the silent inversion `theme/colors.ts` spends
 * twenty lines warning about. Names now say the JOB, so they survive the next
 * palette change.
 *
 * ⚠️ **THE TWO TOKENS THAT INVERT RATHER THAN DARKEN.** `theme/colors.ts` flags
 * both and both apply here:
 *
 *   --brand-ink   Was honeyInk #A55F27 (4.58 on cream). On soot that is **3.95
 *                 and fails**, and honey itself is **7.89**. So brand-coloured
 *                 type is now `#DA9660`, the same value as the fill. Going back
 *                 to a light palette means putting honeyInk back here or every
 *                 link on the site silently drops to 2.29.
 *   --ink-on-brand Dark ink on a honey fill, never white. White on honey is
 *                 **2.47 and was live on the CTA until this commit**.
 *
 * ⚠️ **NO LIGHT MODE, DELIBERATELY.** The old file carried a
 * `prefers-color-scheme:dark` block that inverted a cream site. There is now one
 * palette, it is the app's, and a member who arrives in light mode should still
 * see the product. `color-scheme:dark` is set so scrollbars and form controls
 * follow rather than flashing white.
 *
 * 📌 **Every pair below was measured, not chosen by eye.** linen on soot 15.32,
 * linenMuted on soot 5.72, honey on soot 7.89, espresso on honey 6.18.
 * ⚠️ **`linenSubtle` #7D6A58 is 3.78 on soot and is NOT used for type here.**
 * The app uses it for placeholders and the steam in the mark, where nobody has
 * to read it. The site's footer is a legal line people do read.
 *
 * 🔴 **THE FONTS ARE THE APP'S OWN, SELF-HOSTED.** Fraunces for display and
 * Karla for body, copied from the same `@expo-google-fonts` packages the app
 * loads. Not a Google Fonts link: `default-src 'self'` in `_headers` would
 * refuse it, and a third-party font host on the page a vendor lands on is a
 * request we do not need to make.
 */

@font-face { font-family:'Fraunces'; src:url('./fonts/Fraunces_600SemiBold.ttf') format('truetype'); font-weight:600; font-display:swap; }
@font-face { font-family:'Fraunces'; src:url('./fonts/Fraunces_700Bold.ttf') format('truetype'); font-weight:700; font-display:swap; }
@font-face { font-family:'Karla'; src:url('./fonts/Karla_400Regular.ttf') format('truetype'); font-weight:400; font-display:swap; }
@font-face { font-family:'Karla'; src:url('./fonts/Karla_600SemiBold.ttf') format('truetype'); font-weight:600; font-display:swap; }

:root {
  color-scheme: dark;

  /* ⚠️ The tea has its OWN token and does not read from --brand. The app split
     `tea` out of `colors.primary` on 2026-08-03 for exactly this reason: four
     brand marks filled a glass from the brand colour, which was right only by
     accident while the two happened to be the same value. Kettle keeps honey as
     the brand, so this still matches what the app draws; the coupling does not
     come back. */
  --tea:#DA9660;
  /* colors.textSubtle on Kettle, which is what the app draws the steam in.
     ⚠️ This said #8C7C73 until 2026-08-03, which was the LIGHT palette's
     textSubtle. The mark was steaming in the wrong colour. */
  --steam:#7D6A58;

  /* Grounds — palette.soot / sootRaised / sootDeep */
  --bg:#100C0A; --surface:#171210; --surface-deep:#0A0705;
  /* Borders — palette.ash / ashSoft */
  --border:#2B2119; --border-soft:#211A14;
  /* Type — palette.linen / linenMuted */
  --ink:#ECE3D7; --ink-soft:#9A8878;
  /* Brand — palette.honey / honeyDeep, and espresso as ink on top of it */
  --brand:#DA9660; --brand-deep:#CF7630; --brand-ink:#DA9660; --ink-on-brand:#2E2320;

  --display:'Fraunces', Georgia, serif;
  --body:'Karla', ui-sans-serif, -apple-system, sans-serif;
}
* { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }
body {
  margin:0; background:var(--bg); color:var(--ink);
  font-family:var(--body); font-size:17px; line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
/* 🔴 **THE ACTUAL CAUSE OF "SPACING ISSUES ALL OVER THE SITE"** (owner,
   2026-08-03), and it was not the paragraph margins I fixed first.

   `.wrap` and `section` both set the `padding` SHORTHAND on the same elements
   (`<section class="wrap">`). A class beats an element selector, so
   `.wrap { padding:0 24px }` was silently wiping the 56px of top padding every
   section thought it had. **Every vertical gap on the page was whatever the
   previous element's margin happened to be**, which is why nothing lined up and
   nothing looked broken either.

   ⚠️ **Logical properties, so the two can never collide again.** `.wrap` owns
   the horizontal, sections own the vertical, and neither uses the shorthand.
   Found by reading the cascade after the browser reported gaps that did not
   match the stylesheet. */
.wrap { max-width:720px; margin:0 auto; padding-inline:24px; }

/* ------------------------------------------------------------- header --- */
header { padding-block:28px 0; }
header .wrap { display:flex; align-items:center; gap:10px; }
.mark { width:30px; height:30px; flex:none; }
.brand { font-family:var(--display); font-weight:700; font-size:19px; letter-spacing:-.01em;
  color:var(--ink); text-decoration:none; }

/* --------------------------------------------------------------- hero --- */
.hero { padding-block:56px 8px; text-align:center; }
/* ⚠️ `color` is what the glass STROKE inherits (`currentColor` in the mark), so
   this is the outline of the cups and not decoration. It is `--ink`, the same
   `colors.text` the app strokes them in. */
.hero .glasses { width:116px; height:auto; margin:0 auto 30px; display:block; color:var(--ink); }
h1 { font-family:var(--display); font-weight:600; font-size:clamp(38px, 7vw, 56px);
  line-height:1.08; letter-spacing:-.025em; margin:0; }
/* ⚠️ The headline's break is chosen on a wide screen and wrong on a narrow one.
   On a 390px phone the hard break made three lines reading "Find someone /
   worth / sharing a cup with.", orphaning a single word in the middle of the
   most important sentence on the site. Below 640px the line wraps on its own.
   Found by rendering at 390px, not by reading. */
.wide-only { display:none; }
@media (min-width:640px) { .wide-only { display:inline; } }
/* ⚠️ **`margin:20px auto 0` CENTRED THIS BLOCK ON EVERY PAGE, AND IT IS ONLY
   RIGHT ON THE HERO.** On the venues page the lede is left-aligned text in a
   centred box, so it sat indented 75px from the left while the h1 above it and
   every paragraph below it ran full width. It read as a broken quote block.
   Owner spotted it; measured in the browser rather than guessed at.

   The centring now belongs to the hero, which is where the text is centred too. */
.lede { font-size:19px; color:var(--ink-soft); margin-top:20px; max-width:30em; }
.hero .lede { margin-inline:auto; }
.opens { display:inline-flex; align-items:center; gap:8px; margin-top:28px;
  padding:9px 18px; border-radius:999px; background:var(--surface);
  border:1px solid var(--border); font-size:15px; color:var(--ink-soft); }
.opens b { color:var(--brand-ink); font-weight:600; }
.dot { width:7px; height:7px; border-radius:50%; background:var(--brand); flex:none; }

/* -------------------------------------------------------------- cards --- */
.pillars { display:grid; gap:16px; margin:0; align-items:stretch; }
@media (min-width:640px) { .pillars { grid-template-columns:1fr 1fr; } }
/* ⚠️ `height:100%` so two cards in a row are the same height whatever their
   text length. Without it a short card floats and the grid looks ragged.

   ⚠️ **On a dark ground the BORDER is what separates a card, not the fill.**
   soot and sootRaised are a 1.05 contrast ratio apart, so a card drawn only by
   its background is invisible. The app has the same pairing and gets away with
   it because its cards carry a border too. Judged by rendering at full width,
   not by the ratio, which compresses to meaninglessness this far down. */
.pillar { background:var(--surface); border:1px solid var(--border);
  border-radius:18px; padding:22px 24px; height:100%; }
/* ⚠️ These were `<h3>` and the page went h1 straight to h3, skipping a level,
   because the pillars appear before the first `<h2>` on the page. Somebody
   navigating by headings hits a gap. They are `<h2>` now and this rule keeps the
   size they always had: the heading LEVEL is structure, the size is design, and
   they do not have to agree. */
.pillar h2 { font-family:var(--display); font-weight:600; font-size:19px; margin:0 0 6px;
  letter-spacing:-.01em; color:var(--ink); }
.pillar p { margin:0; font-size:16px; color:var(--ink-soft); }

/* -------------------------------------------------------------- blocks -- */
/* ⚠️ ONE rhythm, applied to sections only. The first version had `.pillars`
   carrying a top margin AND sections carrying padding, so wherever the two met
   the gap was different from everywhere else. The owner saw it as "boxes in
   unequal spacing" and it was exactly that. */
section { padding-block:56px 0; }
section:last-of-type { padding-block-end:8px; }
h2 { font-family:var(--display); font-weight:600; font-size:27px; letter-spacing:-.02em;
  margin:0 0 12px; }
p { margin:0 0 14px; }
/* 🔴 **THE CAUSE OF "SPACING ISSUES ALL OVER THE SITE"** (owner, 2026-08-03).
   Sections space themselves with padding, but the LAST paragraph in a section
   also carried its own 14px bottom margin, so a gap was 56px where a section
   ended on a heading and 70px where it ended on text. Nothing looked broken and
   nothing lined up. Measured in the browser rather than guessed at. */
section > *:last-child,
.wrap > *:last-child,
.panel > *:last-child,
.faq > *:last-child { margin-bottom:0; }
a { color:var(--brand-ink); text-decoration:underline; text-underline-offset:2px; }
/* ⚠️ **DARK INK ON THE FILL, NOT WHITE.** White on honey is 2.47 and was live
   on this button until 2026-08-03. espresso on honey is 6.18, and it is what
   `colors.textOnPrimary` has been in the app since 2026-07-26. */
.cta { display:inline-block; margin-top:6px; padding:13px 24px; border-radius:999px;
  background:var(--brand); color:var(--ink-on-brand); font-weight:600;
  text-decoration:none; font-size:16px; }
.cta:hover { background:var(--brand-deep); }
.panel { background:var(--surface); border:1px solid var(--border);
  border-radius:18px; padding:28px 26px; }

/* ------------------------------------------------------------- waitlist --- */
/*
 * The email field, hand-written rather than embedded.
 *
 * 🔴 **KIT'S OWN EMBED WAS NOT USED AND THAT IS THE POINT.** Its snippet ships a
 * `<script>` from `f.convertkit.com`, about 12KB of its own CSS, a stock
 * photograph, a "Built with Kit" badge and an analytics config block. All that
 * is kept is the endpoint and the field name, so `script-src 'none'` in
 * `web/_headers` never has to move and the field can be the site's own colours
 * instead of a widget dropped into the page.
 *
 * ⚠️ **`stretch` rather than `center`, so the button matches the field height**
 * whatever the type scale does. Two controls side by side that disagree by three
 * pixels is the thing nobody can name and everybody sees.
 */
.signup { display:flex; flex-wrap:wrap; gap:10px; align-items:stretch; margin-top:18px; }
.signup-field {
  flex:1 1 240px; min-width:0;
  background:var(--bg); color:var(--ink);
  border:1px solid var(--border); border-radius:999px;
  padding:13px 20px; font-family:var(--body); font-size:16px; line-height:1.2;
}
.signup-field::placeholder { color:var(--ink-soft); opacity:1; }
/* ⚠️ A VISIBLE focus ring, in the brand colour. The default outline is invisible
   on a dark ground, and this field is the one thing on the page somebody has to
   be able to find with a keyboard. */
.signup-field:focus-visible {
  outline:2px solid var(--brand); outline-offset:2px; border-color:var(--brand);
}
.signup .cta { margin-top:0; flex:0 0 auto; border:1px solid var(--brand);
  font-family:var(--body); cursor:pointer; }
/* ⚠️ Once the button has wrapped onto its own line it should own that line.
   A half-width button under a full-width field looks like a mistake, and the
   thumb target is smaller for no reason. Found by rendering at 390px. */
@media (max-width:480px) { .signup .cta { flex:1 1 100%; } }
.signup-note { margin-top:12px; font-size:14.5px; color:var(--ink-soft); }

/* ⚠️ Hides the label from sight, NEVER from a screen reader. `display:none`
   would remove it from the accessibility tree and leave the field unlabelled. */
.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.panel h2 { margin-top:0; }
.panel p { color:var(--ink-soft); }
/* The trailing housekeeping links. Quieter than a section, because they are
   not the point of the page. */
.small p { font-size:15.5px; color:var(--ink-soft); margin-bottom:8px; }

/* ------------------------------------------------------- where and faq --- */

.places { display:grid; gap:2px 28px; margin:18px 0 20px; }
@media (min-width:620px) { .places { grid-template-columns:1fr 1fr; } }
.places div { padding:11px 0; border-bottom:1px solid var(--border); }
.places b { display:block; font-family:var(--display); font-weight:600; font-size:17px;
  color:var(--ink); }
.places span { display:block; font-size:15.5px; color:var(--ink-soft); margin-top:2px; }
.note { font-size:15.5px; color:var(--ink-soft); }

.faq { margin:18px 0 0; }
.faq dt { font-family:var(--display); font-weight:600; font-size:18px; margin-top:26px;
  color:var(--ink); }
.faq dt:first-of-type { margin-top:0; }
.faq dd { margin:7px 0 0; color:var(--ink-soft); font-size:16px; }

/* --------------------------------------------------------------- legal -- */
.doc { padding-block-start:40px; }
.doc h1 { font-size:clamp(30px, 5vw, 40px); text-align:left; }
.doc h2 { font-size:21px; margin-top:34px; }
.doc .meta { font-size:14px; color:var(--ink-soft); margin-top:10px; }
.doc ul { padding-left:22px; }
.doc li { margin-bottom:9px; color:var(--ink-soft); }
.doc p { color:var(--ink-soft); }
.notice { margin:22px 0 6px; padding:16px 18px; background:var(--surface);
  border:1px solid var(--border); border-radius:14px; font-size:15px;
  color:var(--ink-soft); }
.notice b { color:var(--brand-ink); }

/* --------------------------------------------------- statutory disclosure --- */
/*
 * 🔴 **A STATUTORY DISCLOSURE, NOT A DESIGN ELEMENT. DO NOT RESTYLE IT.**
 *
 * The web twin of `components/BackgroundCheckNotice`, and it carries that
 * component's rules exactly. **New Jersey's Internet Dating Safety Act** (P.L.
 * 2007, c.272) requires a dating service that runs no criminal background
 * screening to say so **"in bold, capital letters in at least 12-point type"**,
 * in at least two of: email messages, click-through acknowledgements, member
 * profiles, or **the website home page**.
 *
 * 🔴 **IT IS ENFORCED. NEW JERSEY SETTLED WITH BUMBLE FOR $315,000 IN 2024**,
 * and failing it is an unlawful practice under the NJ Consumer Fraud Act, which
 * carries treble damages.
 *
 * ⚠️ **WHAT MAY NOT CHANGE: the capitals, the weight, and the size.** 17px is
 * 12.75pt, comfortably over the floor, and it is stated in `pt` here so that a
 * future type-scale change cannot quietly take it under. **Never set this in a
 * relative unit that could resolve smaller, and never lowercase it in CSS** —
 * the markup is capitals so that copy-paste and a stripped stylesheet both keep
 * the disclosure, and `text-transform` is belt and braces on top of that.
 *
 * ⚠️ **The flat, ugly wording is deliberate** and is the app's, verbatim. A
 * friendlier version is the over-promise CLAUDE.md's safety-copy rule forbids.
 *
 * 🔴 **`!important` ON ALL FOUR STATUTORY PROPERTIES, AND IT IS NOT LAZINESS.**
 * The first version of this rule was a plain `.statutory {}`, and both pages
 * that carry the disclosure already had a selector that beat it on specificity:
 * `.small p` on the home page and `.doc p` on the questions page, each (0,1,1)
 * against this rule's (0,1,0).
 *
 * 🔴 **THAT WAS NOT A COSMETIC LOSS. `.small p` SETS `font-size:15.5px`, WHICH
 * IS 11.6pt, AND THE STATUTORY FLOOR IS 12pt.** The disclosure was rendering
 * under the legal minimum on the home page, in the muted grey meant for
 * housekeeping links, and it looked completely fine. **Caught by rendering the
 * page and looking at it; the unit test passed, because it read the declared
 * rule rather than the computed one.** Second time a class has silently beaten
 * an element rule in this file: see the `.wrap` / `section` padding note above.
 *
 * ⚠️ **So the four properties the statute names are the four that are
 * `!important`**: the size, the weight, the capitals, and legibility. Anything
 * that is presentation rather than law (the rule above it, the spacing, the
 * centring) is left ordinary on purpose, so this is a fence around the legal
 * requirement and not a fence around a design.
 */
/*
 * 📝 **QUIETENED 2026-08-04, AND ONLY THE NON-STATUTORY HALF MOVED** (owner,
 * twice: "that is so on the face", then "should it be on such big text front and
 * center").
 *
 * The owner was right about the cause and it was **the centring**, which was my
 * choice and not the statute's. A centred block of bold capitals is a banner
 * whatever it says. Three things changed, none of them the law:
 *
 * * **Left-aligned**, so it reads as the legal line above the footer, which is
 *   what it is, rather than as an announcement.
 * * **`--ink-soft` instead of `--ink`**, matching the footer text it now sits
 *   with. ⚠️ **5.72:1 on the page ground, comfortably past AA.** The statute
 *   specifies size, weight and case, and says nothing about colour, but a
 *   disclosure nobody can read is concealment, so this was measured rather than
 *   picked. **Do not take it below `--ink-soft`.**
 * * **A wider letter-spacing**, which is what stops capitals at this size
 *   reading as shouting.
 *
 * 🔴 **THE FOUR STATUTORY PROPERTIES DID NOT MOVE AND MUST NOT.** 12.5pt is
 * still over the 12pt floor with margin left for rounding. Bold, capitals and
 * the wording are untouched.
 *
 * 📌 **Both versions were rendered and compared before this was chosen.** The
 * measurement that mattered was not a ratio, it was looking at the two.
 */
.statutory {
  margin-top:40px; padding-top:20px; border-top:1px solid var(--border);
  line-height:1.5; letter-spacing:.04em; text-align:left;
  /* The statutory four. See the note above before touching any of them. */
  font-size:12.5pt !important;
  font-weight:700 !important;
  text-transform:uppercase !important;
  color:var(--ink-soft) !important;
}

/* -------------------------------------------------------------- footer -- */
footer { margin-top:72px; border-top:1px solid var(--border); }
footer .wrap { padding-block:26px 56px; color:var(--ink-soft); font-size:14.5px; }
footer nav { margin-top:12px; display:flex; gap:16px; flex-wrap:wrap; }
