/* ============================================================
   Dinner Series
   One stylesheet, shared by every page. See docs/style-guide.md.
   ============================================================ */

:root {
  /* ---- color ---- */
  --paper: #FAF9F6;
  --ground: #F1EFE8;
  --ink: #1C1C1A;
  --ink-muted: #8A857E;
  --rule: #E6E3DD;

  /* The field is the deeper tone at the edges of the page, where the linework
     lives. The centre lifts back to near --paper, so the measure sits on the
     brightest part of the surface. See --contour below. */
  --field: #F4F1E8;

  /* ---- type ----
     --display is the title face, used on the h1 and nowhere else. It is the
     one thing meant to be swapped. See docs/titles.html for the candidates.

     Current direction: ultralight condensed ITALIC. Extreme thinness and a
     long italic sweep are the point, so the h1 sets font-style: italic and
     weight 300. Reference is PP Editorial New Ultralight Italic (commercial);
     this is the closest free equivalent and it costs no extra request,
     because the text face already loads its italic. */
  --display: "Cormorant Garamond", Georgia, serif;
  --text: "Cormorant Garamond", Georgia, serif;

  /* Sharper, more Didone alternative: Playfair Italic pulled narrow. Needs
     &family=Playfair:ital,opsz,wdth,wght@1,5..1200,87.5..112.5,300..900
     added back to the font URL, then set
       --display: "Playfair", Georgia, serif;
       --display-vf: "opsz" 100, "wdth" 87.5, "wght" 300;
     and apply --display-vf in the h1 rule. */
  --display-vf: normal;

  /* ---- texture: contour linework in the margins, study 11 ----

     Two formations that bleed off the left and right edges of the viewport,
     with a clear channel down the middle where the text sits. Both are drawn,
     not photographed, which is the whole reason this survives section 14.

     Each is one curve repeated at irregular offsets: a cluster of four, then
     the cluster repeated at six wider offsets. That two-level rhythm is what
     keeps it from reading as corduroy. non-scaling-stroke holds the lines at
     exactly 1px however far the SVG is scaled.

     The readable, indented source is docs/textures.html, study 11. Edit there
     first, then re-encode. Roughly 1.5KB the pair. */
  --contour-l: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 900' preserveAspectRatio='xMinYMid slice'%3E%3Cdefs%3E%3Cpath id='l' fill='none' stroke='%236B5B3E' stroke-width='1' vector-effect='non-scaling-stroke' d='M8,-30 C -14,120 34,210 12,330 C -6,430 44,510 18,640 C -4,750 40,830 14,940'/%3E%3Cg id='q'%3E%3Cuse href='%23l'/%3E%3Cuse href='%23l' x='6'/%3E%3Cuse href='%23l' x='13'/%3E%3Cuse href='%23l' x='21'/%3E%3C/g%3E%3C/defs%3E%3Cuse href='%23q'/%3E%3Cuse href='%23q' x='34'/%3E%3Cuse href='%23q' x='72'/%3E%3Cuse href='%23q' x='118'/%3E%3Cuse href='%23q' x='172'/%3E%3Cuse href='%23q' x='236'/%3E%3C/svg%3E");
  --contour-r: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 260 900' preserveAspectRatio='xMaxYMid slice'%3E%3Cdefs%3E%3Cpath id='l' fill='none' stroke='%236B5B3E' stroke-width='1' vector-effect='non-scaling-stroke' d='M8,-30 C -14,120 34,210 12,330 C -6,430 44,510 18,640 C -4,750 40,830 14,940'/%3E%3Cg id='q'%3E%3Cuse href='%23l'/%3E%3Cuse href='%23l' x='7'/%3E%3Cuse href='%23l' x='15'/%3E%3Cuse href='%23l' x='24'/%3E%3C/g%3E%3C/defs%3E%3Cg transform='translate(260,0) scale(-1,1)'%3E%3Cuse href='%23q'/%3E%3Cuse href='%23q' x='38'/%3E%3Cuse href='%23q' x='80'/%3E%3Cuse href='%23q' x='134'/%3E%3Cuse href='%23q' x='196'/%3E%3C/g%3E%3C/svg%3E");

  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* To self-host a licensed display face (PP Editorial New, Canela, Ogg,
   Gladysh): drop the woff2 in /fonts, uncomment, and set --display.
@font-face {
  font-family: "Display";
  src: url("/fonts/display-italic.woff2") format("woff2");
  font-weight: 200;
  font-style: italic;
  font-display: swap;
}
Then: --display: "Display", Georgia, serif;
and drop font-weight from the h1 rule if the file is a single weight.
*/

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  color: var(--ink);
  font-family: var(--text);
  font-weight: 400;
  font-size: 1.1875rem;
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;

  /* Verified against the actual woff2 Google serves: Cormorant Garamond has
     NO `onum` feature, so this declaration is inert. It is kept anyway because
     the figures are already oldstyle by default (3, 5, 7 and 9 descend, 6
     ascends, the rest sit at x-height), which is what we want, and because the
     declaration starts doing real work the moment --text or --display is
     swapped for a face that defaults to lining. The font does ship `lnum`, so
     `lining-nums` below is genuine, not a no-op. */
  font-variant-numeric: oldstyle-nums;

  /* An inverted vignette: the field is deepest at the edges, under the
     linework, and lifts to near --paper behind the measure. It does tonally
     what the mask on html::before does geometrically. */
  background-color: var(--field);
  background-image:
    radial-gradient(90rem 70rem at 50% 42%, rgba(255,254,250,0.92), transparent 70%);
  background-attachment: fixed;

  animation: settle 600ms ease-out both;
}

/* Linework. Fixed to the viewport, so it does not stretch with page length.
   Two layers hugging the left and right edges; the mask fades them out before
   they reach the 30rem column. Sits under the grain, which is body::before.

   The mask is measured from the centre in rem, not in percent, because what
   the lines have to clear is the 30rem column, which does not change with the
   viewport. 15.5rem is the half-column plus a hair; 22rem is where the fade
   begins. One rule then holds at every desktop width, and the formations
   simply have less room to show as the window narrows.

   Below 48rem there is no margin left to clear, so the phone gets its own
   percentage mask and the lines drop to a whisper at the extreme edges.
   Section 5: text never sits on a perceptible feature. */
html::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--contour-l), var(--contour-r);
  background-repeat: no-repeat;
  background-position: left center, right center;
  background-size: 34vw 100%, 30vw 100%;
  opacity: 0.16;
  -webkit-mask-image: linear-gradient(90deg,
    #000 0,
    rgba(0,0,0,0.35) calc(50% - 22rem),
    transparent calc(50% - 15.5rem),
    transparent calc(50% + 15.5rem),
    rgba(0,0,0,0.35) calc(50% + 22rem),
    #000 100%);
  mask-image: linear-gradient(90deg,
    #000 0,
    rgba(0,0,0,0.35) calc(50% - 22rem),
    transparent calc(50% - 15.5rem),
    transparent calc(50% + 15.5rem),
    rgba(0,0,0,0.35) calc(50% + 22rem),
    #000 100%);
}

@media (max-width: 48rem) {
  html::before {
    background-size: 15vw 100%, 13vw 100%;
    opacity: 0.08;
    -webkit-mask-image: linear-gradient(90deg, #000 0%, rgba(0,0,0,0.3) 10%, transparent 24%, transparent 76%, rgba(0,0,0,0.3) 90%, #000 100%);
    mask-image: linear-gradient(90deg, #000 0%, rgba(0,0,0,0.3) 10%, transparent 24%, transparent 76%, rgba(0,0,0,0.3) 90%, #000 100%);
  }
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image: var(--grain);
  opacity: 0.05;
  mix-blend-mode: multiply;
}

@keyframes settle { from { opacity: 0; } to { opacity: 1; } }

.page {
  position: relative;
  z-index: 2;
  max-width: 30rem;
  margin: 0 auto;
  padding: 8rem 1.5rem 10rem;
}

/* ============================================================
   Navigation: fixed trigger, left drawer
   ============================================================ */

.index-trigger {
  position: fixed;
  top: 1.75rem;
  left: 1.75rem;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 44px;
  padding: 0 0.25rem;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--text);
  color: var(--ink);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.24em;
}
.index-trigger .strokes { display: inline-flex; flex-direction: column; gap: 3px; }
.index-trigger .strokes i { display: block; width: 13px; height: 1px; background: var(--ink); }
.index-trigger:hover { color: var(--ink-muted); }
.index-trigger:hover .strokes i { background: var(--ink-muted); }
.index-trigger:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }

.scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(28,28,26,0.18);
  opacity: 0;
  visibility: hidden;
  transition: opacity 400ms ease, visibility 400ms;
}

.drawer {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 70;
  width: min(20rem, 82vw);
  background: var(--paper);
  border-right: 1px solid var(--rule);
  padding: 8rem 2.25rem 2.25rem;
  transform: translateX(-100%);
  transition: transform 420ms cubic-bezier(0.32, 0.72, 0, 1);
  display: flex;
  flex-direction: column;
}

body.index-open .scrim { opacity: 1; visibility: visible; }
body.index-open .drawer { transform: translateX(0); }

.drawer h2 {
  font-size: 0.625rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--ink-muted);
  margin: 0 0 2rem;
  text-align: left;
}
.drawer nav ul { list-style: none; margin: 0; padding: 0; }
.drawer nav li { margin-bottom: 1.5rem; }
.drawer nav a {
  font-size: 1.3125rem;
  font-weight: 300;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
  display: inline-block;
  min-height: 32px;
}
.drawer nav a:hover { color: var(--ink-muted); }
.drawer nav a[aria-current="page"] { font-style: italic; }
.drawer nav a[aria-current="page"]::after {
  content: "";
  display: block;
  width: 1.5rem;
  height: 1px;
  background: var(--ink);
  margin-top: 0.5rem;
}
.drawer .drawer-foot {
  margin-top: auto;
  padding-top: 3rem;
  font-size: 0.75rem;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.2em;
}
.drawer-close {
  position: absolute;
  top: 1.75rem;
  left: 2.25rem;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font-family: var(--text);
  color: var(--ink-muted);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.24em;
}
.drawer-close:hover { color: var(--ink); }
.drawer-close:focus-visible,
.drawer nav a:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }

/* ============================================================
   Masthead
   ============================================================ */

/* The masthead escapes the prose column. At 80px the date is about 446px wide,
   and the 30rem column only offers 432px of it, so the title would break as
   "August / 15, 2026" and split the day from the month. A masthead is allowed
   to be wider than the measure, so it takes the room it needs and the prose
   stays at 30rem underneath. The left/translate pair is what re-centres a child
   wider than its parent. */
.masthead {
  text-align: center;
  margin-bottom: 7rem;
  position: relative;
  left: 50%;
  width: min(38rem, calc(100vw - 3rem));
  transform: translateX(-50%);
}

.series {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.3em;
  color: var(--ink-muted);
  margin: 0 0 2rem;
}

/* The title: Cormorant Garamond Light Italic, chosen from swatch 01.
   Italic is register, not emphasis. Tracking stays at zero, because the
   reference specimen is set tight with the letters nearly touching.

   80px at the top of the range, per the 70 to 80 call. It eases down to
   56px on a narrow phone so the date stays on one line, since a date
   broken across two lines reads as a mistake. For a hard fixed size
   instead, replace the clamp with a single value. */
h1 {
  font-family: var(--display);
  font-variation-settings: var(--display-vf);
  font-style: italic;
  font-weight: 300;
  /* Floor is 48px, not 56px, purely so the date still fits one line on a
     320px screen. Measured: the date runs about 5.43px wide per 1px of font
     size, and a 320px viewport leaves the masthead 272px. Above roughly a
     343px viewport the vw term takes over and the floor never applies. */
  font-size: clamp(3rem, 14vw, 5rem);
  line-height: 1.05;
  letter-spacing: 0;
  margin: 0 0 1.5rem;
  text-wrap: balance;

  /* The title is a date now, so figure style is the most visible typographic
     decision on the page. Cormorant's default figures are oldstyle, so the 1
     and 2 of "August 15, 2026" sit at x-height while the 5 descends. That
     reads as typesetting rather than signage, which suits the register.

     To try the squarer, more masthead-like alternative, change this one line
     to `lining-nums`. That switch is real: the font ships `lnum`. */
  font-variant-numeric: oldstyle-nums;
}

.numeral {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.25em;
  color: var(--ink-muted);
  margin: 0;
  font-variant-numeric: lining-nums;
}

/* ============================================================
   Prose and labels
   ============================================================ */

h2 {
  font-size: 0.6875rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--ink-muted);
  text-align: center;
  margin: 0 0 3rem;
}

.lede { font-weight: 300; font-size: 1.3125rem; line-height: 1.7; margin: 0 0 2rem; }

p { margin: 0 0 2rem; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

section { margin-bottom: 7rem; }
section:last-of-type { margin-bottom: 0; }
@media (min-width: 48rem) { section { margin-bottom: 10rem; } }

/* A section that follows a .divider. Was an inline margin-top, which meant it
   beat the print stylesheet and blew the menu card to three pages. */
.after-rule { margin-top: 7rem; }

/* The lede is centred, so the whole page is now centred: masthead, prose,
   Particulars, menu, wine, fine print.

   This reverses the earlier rule against centred paragraphs, and it survives
   for a specific reason: the lede is four short paragraphs now, not one block.
   The longest is three lines, which is about the limit before a ragged left
   edge starts costing a reader the start of each line. If a paragraph here
   ever grows past three or four lines, this is the first thing to revisit.

   text-wrap: balance is load-bearing rather than decorative. Centred text
   lives or dies on an even rag, and balance is what evens it. */
.intro { text-align: center; }
.intro p { text-wrap: balance; }

/* The wine section is centred like the menu, and its first line is body size
   rather than fine print. */
.wine { text-align: center; }
.wine p { margin-bottom: 2rem; }
.wine p:last-child { margin-bottom: 0; }

a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: var(--rule);
  transition: text-decoration-color 250ms ease;
}
a:hover { text-decoration-color: var(--ink-muted); }
a:focus-visible { outline: 1px solid var(--ink); outline-offset: 3px; }

.divider {
  width: 1.5rem;
  height: 1px;
  background: var(--rule);
  border: 0;
  margin: 0 auto;
}

/* ============================================================
   The Particulars
   ============================================================ */

.particulars { margin: 0; text-align: center; }
.particulars div { margin-bottom: 2.5rem; }
.particulars div:last-child { margin-bottom: 0; }
.particulars dt {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--ink-muted);
  margin-bottom: 0.25rem;
}
.particulars dd { margin: 0; font-size: 1.1875rem; line-height: 1.5; }

/* ============================================================
   The Menu
   ============================================================ */

.menu-note {
  text-align: center;
  font-size: 0.875rem;
  font-style: italic;
  color: var(--ink-muted);
  margin: -1.5rem 0 3.5rem;
}

.menu { list-style: none; padding: 0; margin: 0; text-align: center; }
.menu li { margin-bottom: 3.5rem; }
.menu li:last-child { margin-bottom: 0; }
.course {
  display: block;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--ink-muted);
  margin-bottom: 0.5rem;
}
.dish { display: block; font-size: 1.1875rem; letter-spacing: 0.01em; line-height: 1.4; }
.desc {
  display: block;
  font-weight: 300;
  font-style: italic;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-muted);
  margin-top: 0.25rem;
}

/* ============================================================
   RSVP
   ============================================================ */

.rsvp { text-align: center; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 2.5rem;
  border: 1px solid var(--ink);
  color: var(--ink);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  text-decoration: none;
  transition: border-color 250ms ease, color 250ms ease;
}
.btn:hover { border-color: var(--ink-muted); color: var(--ink-muted); }

.fine {
  font-size: 0.875rem;
  line-height: 1.75;
  color: var(--ink-muted);
  text-align: center;
}

/* ============================================================
   Previous dinners
   ============================================================ */

.archive { list-style: none; margin: 0; padding: 0; }
.archive li { border-bottom: 1px solid var(--rule); }
.archive li:first-child { border-top: 1px solid var(--rule); }
.archive a {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  align-items: baseline;
  gap: 0 1.25rem;
  padding: 1.75rem 0.25rem;
  min-height: 44px;
  text-decoration: none;
  transition: opacity 250ms ease;
}
.archive a:hover { opacity: 0.55; }
.archive .num {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--ink-muted);
  font-variant-numeric: lining-nums;
}
.archive .when { font-size: 1.1875rem; line-height: 1.4; }
.archive .what {
  display: block;
  grid-column: 2;
  font-weight: 300;
  font-style: italic;
  font-size: 1rem;
  color: var(--ink-muted);
  line-height: 1.5;
  margin-top: 0.125rem;
}

.empty {
  text-align: center;
  font-weight: 300;
  font-size: 1.3125rem;
  line-height: 1.7;
  color: var(--ink-muted);
}

/* A past edition, arrived at from the index */
.happened {
  text-align: center;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--ink-muted);
  margin: 0 0 3rem;
  line-height: 2;
}

/* ============================================================
   Preferences
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  body { animation: none; }
  * { transition-duration: 0.01ms !important; }
}

@media (prefers-reduced-transparency: reduce) {
  html::before,
  body::before { display: none; }
  body { background-image: none; background-color: var(--paper); }
}

/* ============================================================
   Print: someone hits Cmd-P and gets a menu card for the table
   ============================================================ */

/* ============================================================
   Print: the card that goes on the table

   Not a printout of the invite. By the time this is on paper the guests are
   in the room, so the lede, the Particulars (cost, Venmo handle, address
   policy) and the fine print are all wrong for it and come out. What is left
   is the date, the four courses, and the wine, on one page.

   To print the full invite instead, delete `.intro`, `.particulars-block`
   and `.fine-print` from the display:none list below.
   ============================================================ */

@media print {
  /* Scale the root, not the body. Everything here is sized in rem, so
     overriding body font-size alone left the rem-based elements (.lede,
     .dish, the labels) at screen size while plain paragraphs shrank. */
  html { font-size: 11pt; }

  body {
    background: #FFF;
    color: #000;
    animation: none;
    font-size: 1rem;
    line-height: 1.5;
  }

  html::before,
  body::before,
  .index-trigger,
  .scrim,
  .drawer,
  .rsvp,
  .intro,
  .particulars-block,
  .fine-print,
  .divider,
  .no-print { display: none !important; }

  /* Keep a measure. `max-width: none` let lines run the full sheet width,
     which is poor on paper and worse on a card. */
  .page { max-width: 5.25in; margin: 0 auto; padding: 0; }

  .masthead { width: auto; left: auto; transform: none; margin-bottom: 2.25rem; }
  h1 { font-size: 30pt; }

  section { margin-bottom: 2rem; page-break-inside: avoid; }
  section:last-of-type { margin-bottom: 0; }
  .after-rule { margin-top: 0; }
  h2 { margin-bottom: 1.25rem; }
  .menu li { margin-bottom: 1.25rem; }
  .wine p { margin-bottom: 1rem; }
  a { text-decoration: none; }
}
