/* ---------------------------------------------------------------
   The public contact page.
   A mailto: alone assumes a mail client is set up and leaves anyone
   on a shared or work machine with nowhere to go, so the address is
   written out here in full: readable, selectable, one tap to copy,
   and still a link for the people whose mail app does open. Lives
   under /welcome/ — the one public folder — with its CSS beside it
   there, because /css stays behind sign-in and the
   Content-Security-Policy allows no inline style (app/security.py).
   --------------------------------------------------------------- */
:root {
  --bg:        #f7f1e6;
  --card:      #fffdf8;
  --ink:       #2a2520;
  --muted:     #686052;
  --line:      #e7ddca;
  --brand:     #3f7d52;
  --brand-ink: #2f6840;
  --surface-2: #f3ecde;
  --herb-soft: #e6efe2;
  --clay:      #ae5727;
  /* The same colours as channels, for the handful of places that need one
     at an alpha, and the blends that used to be written inline. Both are
     here rather than `color-mix()` because this page is the one a crawler
     and a television both land on — see the head of css/rasoi-theme.css. */
  --bg-rgb:    247, 241, 230;
  --brand-rgb: 63, 125, 82;
  --serif: "Newsreader", Georgia, serif;
  --sans:  "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --shadow-sm: 0 1px 2px rgba(63,49,30,.05), 0 6px 18px rgba(63,49,30,.06);
  --shadow-lg: 0 2px 6px rgba(63,49,30,.06), 0 24px 60px rgba(63,49,30,.14);
}

/* The same palette after dark. This page is outside the auth gate and can't
   reach /css or ask the server anything, so it carries its own copy of the
   tokens, kept in step with web/css/theme-dark.css — which is the original,
   and where the reasoning for each value lives. The attribute is set by the
   inline script in <head> from the same localStorage key the app writes, so
   someone who chose dark inside Rasoi gets a dark page here too, and a
   first-time visitor gets whatever their device says. With JavaScript off
   the attribute is never set and this stays the light page it has always
   been. */
:root[data-theme="dark"] {
  --bg:        #15120f;
  --card:      #211d1a;
  --ink:       #edebe7;
  --muted:     #a39e96;
  --line:      #33302b;
  --brand:     #3b834e;
  --brand-ink: #95d7a2;
  --surface-2: #1b1815;
  --herb-soft: #1c3422;
  --clay:      #ce7443;
  --bg-rgb:    21, 18, 15;
  --brand-rgb: 59, 131, 78;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.45), 0 24px 60px rgba(0, 0, 0, 0.6);
  color-scheme: dark;
}
/* The washes behind the page: mid-lightness colours laid over paper, which
   need a little more of themselves to register over near-black. */
[data-theme="dark"] .glow {
  background:
    radial-gradient(58% 46% at 84% -6%, rgba(173, 86, 34, 0.22), transparent 62%),
    radial-gradient(50% 44% at 4% 2%,   rgba(51, 115, 68, 0.2), transparent 60%);
}
/* Google's own dark treatment for the sign-in button. Its light one is
   specified down to the hex and so is this, which is why these three don't
   come from the palette — and a white button would be the single brightest
   thing on the page by a distance. */
[data-theme="dark"] .gbtn { background: #131314; color: #e3e3e3; border-color: #8e918f; }
/* The primary button darkens its fill on hover by reaching for `--brand-ink`,
   which after dark is the *lighter* green — and its white type would be
   sitting on it. Deepen instead, which is the same gesture. */
[data-theme="dark"] .btn.primary:hover { background: #2c6d3e; }


*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; font-family: var(--sans); color: var(--ink);
  background: var(--bg); line-height: 1.55; overflow-x: hidden;
}
a { color: inherit; }
.wrap { width: min(760px, 100% - 40px); margin-inline: auto; }
.glow {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(58% 46% at 84% -6%, rgba(192,97,47,.17), transparent 62%),
    radial-gradient(50% 44% at 4% 2%,   rgba(63,125,82,.16), transparent 60%);
}
@media (max-width: 560px) { .wrap { width: min(760px, 100% - 32px); } }

/* ---------------- nav ---------------- */
header.nav {
  position: sticky; top: 0; z-index: 30;
  backdrop-filter: saturate(140%) blur(10px);
  background: rgba(var(--bg-rgb), 0.8);
  border-bottom: 1px solid var(--line);
}
.nav-in { display: flex; align-items: center; gap: 18px; height: 66px; }
.brand {
  font-family: var(--serif); font-size: 1.4rem; font-weight: 600;
  letter-spacing: -.015em; text-decoration: none;
  display: inline-flex; align-items: center; gap: 9px; min-height: 44px;
}
.brand .pan {
  width: 32px; height: 32px; border-radius: 10px; background: var(--brand);
  color: #fff; display: grid; place-items: center;
  box-shadow: 0 3px 10px rgba(63,125,82,.35);
}
.pan svg { display: block; }
.nav-links { margin-left: auto; display: flex; align-items: center; gap: 26px; }

/* ---------------- dark mode, in the nav ----------------
   Rasoi starts light and there is one press to say otherwise, on the pages a
   stranger reads as well as inside the app. These pages are outside the gate —
   they cannot ask the server anything — but they are on the same origin, so
   they write the same `rasoi.theme` mirror the app reads, and somebody who
   turns the pitch dark finds the app dark when they sign in.

   Both drawings ship and CSS shows one. /js/theme-boot.js paints the attribute
   before the first frame and wires the button at DOMContentLoaded, so an icon
   chosen in script would visibly correct itself on every load for anyone who
   reads dark. Every rule names both classes: `.theme-btn svg` would be a class
   plus an element, which out-specifies a bare `.theme-ico-sun` and puts the
   moon and the sun on screen together. */
.theme-btn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--muted); cursor: pointer;
  transition: color .18s ease, border-color .18s ease;
}
.theme-btn:hover { color: var(--ink); border-color: var(--brand); }
.theme-btn .theme-ico { display: none; width: 18px; height: 18px; }
.theme-btn .theme-ico-moon { display: block; }
[data-theme="dark"] .theme-btn .theme-ico-moon { display: none; }
[data-theme="dark"] .theme-btn .theme-ico-sun { display: block; }

.gbtn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  background: #fff; color: #3c4043; border: 1px solid #dadce0; border-radius: 11px;
  padding: 9px 16px; min-height: 44px; font-family: var(--sans); font-size: .9rem; font-weight: 600;
  text-decoration: none; box-shadow: 0 1px 2px rgba(60,64,67,.1);
  transition: box-shadow .18s ease, transform .18s ease; white-space: nowrap;
}
.gbtn:hover { box-shadow: 0 6px 20px rgba(60,64,67,.18); transform: translateY(-2px); }
.gbtn svg { flex: none; }

/* ---------------- page ---------------- */
main { padding: 46px 0 20px; }
@media (max-width: 720px) { main { padding: 30px 0 10px; } }
/* 44px, like every other control. It was 22 — the height of the words —
   and it is the only way back on a page someone reached from a footer. */
.back {
  display: inline-flex; align-items: center; gap: 7px; text-decoration: none;
  min-height: 44px; padding-inline: 10px; margin-inline: -10px;
  color: var(--muted); font-size: .9rem; font-weight: 500;
  transition: color .18s ease, gap .18s ease;
}
.back:hover { color: var(--ink); gap: 11px; }
h1 {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(2.2rem, 5vw, 3rem);
  line-height: 1.05; letter-spacing: -.03em; margin: 16px 0 0; text-wrap: balance;
}
.sub { font-size: 1.08rem; color: var(--muted); margin: 12px 0 0; max-width: 34em; }
h2 {
  font-family: var(--serif); font-weight: 600; font-size: clamp(1.4rem, 2.8vw, 1.8rem);
  line-height: 1.15; letter-spacing: -.022em; margin: 0;
}
.kicker { font-size: .78rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--clay); }

/* ---------------- the address ----------------
   The whole point of the page, so it gets the weight of one: big
   enough to read across a room, and one click selects all of it. */
.mailcard {
  margin-top: 30px; background: var(--card); border: 1px solid var(--line);
  border-radius: 22px; box-shadow: var(--shadow-lg); padding: 30px 28px;
  text-align: center;
}
@media (max-width: 560px) { .mailcard { padding: 24px 18px; } }
.mailcard .env {
  width: 46px; height: 46px; border-radius: 14px; margin: 0 auto 16px;
  background: var(--herb-soft); color: var(--brand-ink); display: grid; place-items: center;
}
.addr {
  display: inline-block; font-family: var(--serif); font-weight: 500;
  font-size: clamp(1.5rem, 5.4vw, 2.2rem); letter-spacing: -.02em;
  color: var(--ink); text-decoration: none; line-height: 1.2;
  /* one click grabs the whole address, for the copy-by-hand crowd */
  user-select: all; -webkit-user-select: all;
  border-bottom: 2px solid rgba(var(--brand-rgb), 0.35);
  /* 9px of it is there to clear 44px — the words alone came to 33. */
  padding: 10px 0 4px; transition: border-color .18s ease, color .18s ease;
  word-break: break-word;
}
.addr:hover { color: var(--brand-ink); border-bottom-color: var(--brand); }
.btns { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 24px; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  border-radius: 12px; padding: 12px 20px; font-family: var(--sans);
  font-size: 1rem; font-weight: 600; text-decoration: none; cursor: pointer;
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  /* colour rides along with background — left out, the label would snap to
     its new ink while the fill was still fading, which is a flash of dark
     green on dark green every time the button flips to "Copied". */
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease,
              background .18s ease, color .18s ease;
}
.btn:hover { transform: translateY(-2px); border-color: var(--brand); background: var(--herb-soft); }
.btn.primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn.primary:hover { background: var(--brand-ink); box-shadow: 0 8px 22px rgba(63,125,82,.3); }
.btn svg { flex: none; }
/* The confirmation has to beat :hover — the pointer is still sitting on the
   button at the moment it flips, and the hover rule would otherwise keep the
   dark fill under the newly dark text, leaving "Copied" invisible. */
.btn.copied, .btn.copied:hover,
.btn.primary.copied, .btn.primary.copied:hover {
  background: var(--herb-soft); border-color: var(--brand); color: var(--brand-ink);
  transform: none; box-shadow: none;
}
.note { margin: 16px 0 0; font-size: .88rem; color: var(--muted); }
/* The second mail card — the one that offers the form rather than the address —
   and its opening line, which leads the card instead of trailing whatever was
   above it. Both were `style=""` attributes until this app grew a
   Content-Security-Policy (app/security.py); `style-src 'self'` drops an inline
   style attribute silently, and what that looks like here is a card jammed
   against the one above it. */
.mailcard-write { margin-top: 18px; }
.note-lead { margin: 0 0 14px; }


/* ---------------- what to write about ---------------- */
section.block { margin-top: 56px; }
.lead { color: var(--muted); margin: 10px 0 0; }
.panel {
  background: var(--card); border: 1px solid var(--line); border-radius: 20px;
  box-shadow: var(--shadow-sm); padding: 8px 24px; margin-top: 22px;
}
@media (max-width: 560px) { .panel { padding: 4px 18px; } }
.row { display: flex; gap: 14px; align-items: flex-start; padding: 20px 0; }
.row + .row { border-top: 1px solid var(--line); }
.row .ico {
  width: 32px; height: 32px; border-radius: 10px; flex: none; margin-top: 1px;
  background: var(--surface-2); display: grid; place-items: center; font-size: 1rem;
}
.row h3 { margin: 0 0 4px; font-size: 1.02rem; font-weight: 700; }
.row p { margin: 0; color: var(--muted); font-size: .95rem; }
.row p a { color: var(--brand-ink); }

footer {
  border-top: 1px solid var(--line); margin-top: 56px; padding: 24px 0 36px;
  color: var(--muted); font-size: .86rem;
}
.foot-in { display: flex; flex-wrap: wrap; gap: 10px 22px; align-items: center; }
.foot-in .brand { font-size: 1.12rem; }
.foot-in .right { margin-left: auto; display: flex; flex-wrap: wrap; gap: 2px 12px; }
/* 44px, the same as the landing page's footer and for the same reason —
   these were 21px tall. Padding buys the height; the negative inline margin
   keeps the row reading as it did. */
.foot-in a.flink {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 10px; margin-inline: -10px;
  text-decoration: none;
}
.foot-in a.flink:hover { color: var(--ink); text-decoration: underline; }
/* A middot between items. Five short labels all set at the same weight read as
   one run, and the row says where each one starts but not where the last one
   ended.

   **The two sides of the dot are built out of different pieces, and they have
   to be added up rather than assumed.** Each link carries `padding: 0 10px`
   with `margin-inline: -10px` — negative on *both* sides — to buy a 44px touch
   target without moving the words. So:

     left  = this rule's 12px margin
     right = 10px (own right padding) − 10px (own right margin)
             + 12px (the row's column gap)
             − 10px (next item's left margin) + 10px (its left padding)  = 12px

   which is why the column gap above is 12px and not the 2px it was. Read the
   right-hand side as "the gap, and everything else cancels". At 2px the dot sat
   12px after one word and 2px before the next, which reads as `Privacy ·Terms`
   — correct in the box model and wrong on the page. Change one number here and
   the other one moves.

   `inline-block` stops the hover underline from running through it, and it is
   never on the last item, so no wrapped row ends in a dangling dot. */
.foot-in .foot-links > *:not(:last-child)::after,
.foot-in .right > *:not(:last-child)::after {
  content: "·";
  display: inline-block;
  margin-left: 12px;
  text-decoration: none;
  opacity: .55;
}
/* The page you're standing on, in the row above: text rather than an anchor,
   so five public pages don't each carry a self-link. Same box as .flink so the
   row's rhythm and its 44px targets are unchanged — opacity rather than a
   fainter token because this file carries its own palette twice and a fifth
   colour would be a fifth thing to keep in step. */
.foot-in .fhere {
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 10px; margin-inline: -10px;
  opacity: .62;
}
@media (max-width: 560px) { .foot-in .right { margin-left: 0; } }
.foot-love {
  margin: 18px 0 0; font-family: var(--serif); font-style: italic;
  font-size: .95rem; color: var(--muted);
  display: flex; align-items: flex-start; gap: 7px;
}
/* the heart sits on the first line, not adrift between two when it wraps */
.foot-love .heart { color: var(--clay); flex: none; margin-top: .32em; }

:focus-visible { outline: 3px solid var(--brand); outline-offset: 3px; border-radius: 8px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------------- the feedback form ----------------
   The same four fields as the one inside the app (web/js/feedback.js),
   written out again here because this page is outside the auth gate and
   can't reach /js any more than it can reach /css. Change the wording in
   one and change it in the other.

   The difference is the button: a visitor here usually has no session, and
   the note has to survive a trip to Google and back. It is parked in
   sessionStorage under the key the app reads on boot, and the app shell —
   which is where Google hands the browser back to — finishes the send. */
.fab {
  position: fixed; right: 16px; z-index: 40;
  bottom: calc(16px + env(safe-area-inset-bottom));
  display: inline-flex; align-items: center; gap: 9px;
  min-height: 52px; padding: 0 20px; border-radius: 26px; cursor: pointer;
  border: 1px solid var(--brand); background: var(--brand); color: #fff;
  font-family: var(--sans); font-size: .95rem; font-weight: 600;
  box-shadow: 0 6px 20px rgba(var(--brand-rgb), .34);
  transition: background .18s ease, box-shadow .18s ease, transform .18s ease;
}
.fab:hover { background: var(--brand-ink); transform: translateY(-2px); }
.fab svg { display: block; flex: none; }
/* The button ships `hidden` and the script un-hides it, so a reader with no
   JavaScript is never shown a control that can't open anything. `[hidden]`
   is a UA rule and loses to the author `display` above, so it is restated —
   without this the attribute does nothing at all. */
.fab[hidden] { display: none; }
/* A circle on a phone: the word costs a third of the row it floats over,
   and the label stays in the accessible name either way. */
@media (max-width: 560px) {
  .fab { padding: 0; width: 52px; justify-content: center; }
  .fab-label { display: none; }
}
[data-theme="dark"] .fab { box-shadow: 0 8px 24px rgba(0, 0, 0, .5); }
/* `--brand-ink` after dark is the *lighter* green, with this button's white
   type on it. Deepen instead — the same gesture, the same fix as `.btn`. */
[data-theme="dark"] .fab:hover { background: #2c6d3e; }

.fb-scrim {
  position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(42, 37, 32, .5);
  overflow-y: auto;
}
[data-theme="dark"] .fb-scrim { background: rgba(0, 0, 0, .62); }
.fb-scrim[hidden] { display: none; }
.fb-sheet {
  width: min(520px, 100%); margin: auto;
  background: var(--card); border: 1px solid var(--line);
  border-radius: 20px; box-shadow: var(--shadow-lg); padding: 22px;
}
.fb-sheet h2 { margin: 0 0 4px; }
.fb-sheet .lead { margin: 0 0 16px; }
.fb-field { margin: 0 0 12px; }
.fb-field label, .fb-field .lbl {
  display: block; margin: 0 0 5px;
  font-size: .8rem; font-weight: 600; color: var(--muted);
}
.fb-field input, .fb-field select, .fb-field textarea {
  font: inherit; font-family: var(--sans); width: 100%;
  padding: 10px 12px; min-height: 44px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg); color: var(--ink);
}
.fb-field textarea { min-height: 120px; resize: vertical; }
/* A value, not a field: which app this came from is the server's to decide,
   and a disabled dropdown with one option in it invites a click that does
   nothing. */
.fb-app {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px; border-radius: 10px;
  background: var(--surface-2); border: 1px solid var(--line);
}
.fb-app-name { font-weight: 600; }
.fb-app-note { font-size: .8rem; color: var(--muted); }
.fb-note { margin: 5px 0 0; font-size: .8rem; line-height: 1.45; color: var(--muted); }
.fb-note a { color: var(--brand-ink); }
.fb-err { margin: 10px 0 0; font-size: .85rem; color: var(--clay); }
.fb-err.ok { color: var(--brand-ink); }
.fb-err[hidden] { display: none; }
.fb-actions {
  display: flex; gap: 10px; margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--line); flex-wrap: wrap;
}
.fb-actions .btn { flex: 1 1 auto; justify-content: center; }
.fb-actions .btn:disabled { opacity: .6; cursor: default; transform: none; }
