/* ── CONCIERGE — SHARED STYLESHEET ──
   One file for all six pages. It was six near-identical copies pasted into
   six heads, and the copies had already started to drift; now a change lands
   everywhere or nowhere. Order: the shared core first (tokens, nav, cards,
   quick add, cart, footer, responsive), then the sections only one page
   uses -- shop, product, and the visit/about/arrangements family. */

  /* Newsreader — self-hosted latin subset, optical size pinned to display.
     Georgia is the fallback: it is the face the wordmark is drawn from. */
  @font-face {
    font-family: 'Newsreader';
    font-style: normal;
    font-weight: 300 600;
    font-display: swap;
    src: url('fonts/newsreader-var.woff2') format('woff2');
  }

  :root {
    --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
    /* Secondary type was #bbb (1.92:1) and #ccc (1.61:1) against white, which
       is below the 4.5:1 floor by a wide margin -- unreadable rather than
       quiet. One tone at 5.03:1 for everything subordinate, so it can be
       tuned in one place. */
    --muted: #6f6f6f;
    /* Section rhythm. The page was running 80px between sections and 2px
       between a section title and its content, which read as one continuous
       block of grids rather than as parts. Two values, so the whole page
       breathes or tightens together. */
    --section-gap: 128px;
    --head-gap: 26px;
    /* Cards sat on a 2px hairline gap, which read as one sheet cut into
       pieces rather than as a set of cards. One token so every grid on the
       site opens up together. */
    --card-gap: 16px;
  }

  * { margin: 0; padding: 0; box-sizing: border-box; }

  /* For headings that structure the page for readers and machines but have
     no visual seat, like the homepage h1. */
  .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;
  }

  body {
    background: #fff;
    color: #111;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-weight: 400;
    font-size: 11px;
    letter-spacing: 0.02em;
    -webkit-font-smoothing: antialiased;
  }

  a { color: inherit; text-decoration: none; }

  /* The hidden attribute loses to any author display rule (.qa-field is
     flex), which left the pick-up time field showing on coffee. Script
     hides things with .hidden; this makes that mean it. */
  [hidden] { display: none !important; }

  /* ── NAV ── */
  nav {
    position: sticky;
    top: 0;
    z-index: 100;
    background: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 32px;
    height: 48px;
  }

  /* ── LOGO ── */
  .logo {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #111;
  }

  .logo svg { display: block; fill: currentColor; }
  .logo .lk { width: 25.2px; height: 20px; }
  .logo .lw { width: 79.4px; height: 17px; }

  .nav-r {
    display: flex;
    gap: 32px;
    font-size: 11px;
    color: #111;
  }

  .nav-r a { transition: color 0.15s; cursor: pointer; }
  .nav-r a:hover { color: var(--muted); }

  /* ── COLLAPSED NAV ──
     Below 768 the links leave the bar and become a full-height sheet. One set
     of links, restyled, rather than a second copy: the bag count is written to
     a single element and duplicating it would need two. */
  .nav-toggle {
    display: none;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    flex-direction: column;
    justify-content: center;
    align-items: flex-end;
    gap: 5px;
    margin-right: -4px;
  }

  .nav-toggle span {
    display: block;
    width: 20px;
    height: 1px;
    background: #111;
    transition: transform 0.28s ease, opacity 0.2s ease;
  }

  nav.open .nav-toggle span:first-child { transform: translateY(3px) rotate(45deg); }
  nav.open .nav-toggle span:last-child  { transform: translateY(-3px) rotate(-45deg); }

  /* ── HERO ── */
  /* ── PAGE CEILING ──
     The layout had none, so it did not get better on a large display, only
     bigger: at 2560 a product card measures 612x816 and the hero is 1092
     tall. Content stops at 1600 and centres. Written as padding rather than
     max-width so the nav and footer rules still run edge to edge -- capping
     the elements would have cut those short. Below 1664 the max() picks the
     32px gutter and nothing changes. */
  nav, .hero, .shop, footer {
    padding-left: max(32px, calc((100% - 1600px) / 2));
    padding-right: max(32px, calc((100% - 1600px) / 2));
  }

  .hero { padding-top: 24px; padding-bottom: var(--section-gap); }

  .hero-img {
    position: relative;
    width: 100%;
    aspect-ratio: 16/7;
    background: #f2f2f2;
    overflow: hidden;
    margin-bottom: 16px;
  }

  .hero-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
  }

  /* ── HERO SLIDES ──
     Crossfade rather than slide. The frames share no composition, and a
     horizontal move would fight that. */
  .hero-img .slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 1.1s ease;
  }

  .hero-img .slide.on { opacity: 1; }

  /* The new frames are portrait phone photographs, so their subjects sit low
     in a 16/7 window. Raising the image 50px brings the room into the frame
     and drops the empty wall above it. */
  /* A percentage, not a pixel offset. calc(50% - 50px) needs 100px of vertical
     overflow to stay covered, and below 768 the hero is 3/2 against 3/2
     originals -- zero overflow -- so the shift pushed the frame off the top
     and left a 50px band of background at the foot. A percentage is defined
     against whatever overflow exists, so it cannot expose the box: it moves
     315px of desktop overflow by the same 50px and does nothing at all when
     there is nothing to move. */
  .hero-img img.shift-up,
  .visit-hero-img img.shift-up { object-position: center 66%; }

  @media (prefers-reduced-motion: reduce) {
    .hero-img .slide { transition: none; }
  }

  .hero-meta {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
  }

  .hero-sub {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-bottom: 4px;
  }

  .hero-sub span { display: block; font-size: 11px; color: var(--muted); }
  .hero-sub a { font-size: 11px; color: #111; cursor: pointer; }
  .hero-sub a[target] { color: var(--muted); }
  .hero-sub a:hover { color: #111; }

  .hero-hours {
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-align: right;
    align-self: flex-start;
  }

  .hero-hours span { font-size: 11px; color: var(--muted); }

  /* ── SHOP ── */
  .shop { padding-top: 0; padding-bottom: var(--section-gap); }

  .shop-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: var(--head-gap);
  }

  /* Section and product headlines share the serif. Newsreader runs small at
     a given px against Helvetica, so each of these goes up two. */
  .shop-title {
    font-family: var(--serif);
    font-size: clamp(16px, 1.4vw, 20px);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.07em;
  }

  /* A way out of a section without a second headline: the shop head carries
     the whole catalogue, the About head carries the About page. */
  .head-link {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    border-bottom: 1px solid #eee;
    transition: color 0.15s, border-color 0.15s;
  }
  .head-link:hover { color: #111; border-color: #111; }
  /* A note in the link's place: same type, no underline, no hover. */
  .head-note, .head-note:hover { color: var(--muted); border-bottom: 0; cursor: default; }

  .grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--card-gap);
  }

  .card { cursor: pointer; position: relative; }

  /* ── KEYBOARD ──
     The homepage cards were divs with onclick: nothing a keyboard or a
     screen reader could reach. Each card now carries a real link stretched
     over it -- same click, same look, and a product page underneath it if
     script is gone. The buy button reveals on focus exactly as it does on
     hover, so tabbing shows the same card a mouse sees. */
  .card-hit { position: absolute; inset: 0; z-index: 1; }
  .card-hit:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
  .card-face { z-index: 2; }
  .shop-card:focus-within .card-cta,
  .drink-card:focus-within .card-cta { opacity: 1; transform: none; pointer-events: auto; }

  .card-img {
    width: 100%;
    aspect-ratio: 3/4;
    background: #f7f7f7;
    overflow: hidden;
    position: relative;
  }

  .card-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
    transition: transform 0.5s ease, opacity 0.4s ease, filter 0.5s ease;
  }

  .card:hover .card-img img { transform: scale(1.1); }

  /* ── SHOP CARD ──
     The blend is named at the top of the packshot, the size and price sit at
     the foot. Hover crossfades to the roasted bean and raises a buy button.
     Scrims at both ends because the packshots are pale at the top and the
     bean shots are dark: white has to hold on either. */
  .shop-card .card-alt, .sp-card .card-alt {
    position: absolute;
    inset: 0;
    opacity: 0;
  }

  /* The hover: packshot out, beans in. */
  .shop-card:hover .card-base { opacity: 0; }
  .shop-card:hover .card-alt { opacity: 1; }

  .card-face {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 16px;
    color: #fff;
    background: linear-gradient(to bottom,
      rgba(0,0,0,0.58) 0%, rgba(0,0,0,0.22) 20%, rgba(0,0,0,0) 42%,
      rgba(0,0,0,0) 52%, rgba(0,0,0,0.34) 76%, rgba(0,0,0,0.72) 100%);
    pointer-events: none;
  }

  .card-blend {
    font-family: var(--serif);
    font-size: clamp(17px, 1.5vw, 22px);
    font-weight: 400;
    letter-spacing: -0.01em;
    line-height: 1.1;
  }

  .card-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transition: opacity 0.3s ease;
  }

  /* Two labels, one button. At two-up phone width a card is about 170px wide
     and the full label measures 334px, so the short form is swapped in by
     media query rather than by a resize listener. aria-label carries the full
     sentence either way, and both spans are hidden from the accessibility
     tree so the button is never announced twice. */
  .cta-tight { display: none; }

  .card-cta {
    margin-top: 10px;
    width: 100%;
    padding: 11px 12px;
    border: 0;
    background: #fff;
    color: #111;
    font-family: inherit;
    font-size: 11px;
    letter-spacing: 0.04em;
    cursor: pointer;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.3s ease, transform 0.3s ease, background 0.15s;
    pointer-events: none;
  }

  .shop-card:hover .card-cta { opacity: 1; transform: translateY(0); pointer-events: auto; }

  .card-cta:hover { background: #f0f0f0; }
  .card-cta:disabled { background: rgba(255,255,255,0.35); color: rgba(255,255,255,0.8); cursor: default; }

  /* ── QUICK ADD ──
     One picture, the size, the count, one dark button. It replaces a half
     page product sheet that opened over the grid and still could not carry a
     tasting note: this is the buy step, and everything else about the coffee
     is a click away on its own page.

     The markup is injected by shopify.js rather than written into each page,
     so the panel on the shop cannot drift from the panel on the homepage. */
  .pdp-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 300;
    overflow-y: auto;
    padding: 32px 16px;
  }

  .pdp-overlay.open { display: flex; align-items: flex-start; justify-content: center; }

  .qa-modal {
    background: #fff;
    width: 100%;
    max-width: 420px;
    margin: auto;
    position: relative;
  }

  .qa-x {
    position: absolute;
    top: 8px; right: 8px;
    z-index: 2;
    width: 34px; height: 34px;
    border: 0;
    background: rgba(255,255,255,0.86);
    font-size: 17px;
    line-height: 1;
    color: #111;
    cursor: pointer;
  }
  .qa-x:hover { background: #fff; }

  .qa-panel { padding: 20px 20px 24px; display: flex; flex-direction: column; gap: 14px; }

  .qa-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }

  .qa-back {
    border: 0; background: none; padding: 0;
    font-family: inherit; font-size: 10px;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--muted); cursor: pointer;
  }
  .qa-back:hover { color: #111; }

  .qa-details { color: #111; border-bottom: 1px solid #ddd; padding-bottom: 2px; margin-right: 30px; transition: border-color 0.15s; }
  .qa-details:hover { border-color: #111; }

  .qa-name { font-family: var(--serif); font-size: 26px; font-weight: 400; line-height: 1.1; letter-spacing: -0.01em; }
  .qa-price { font-size: 11px; color: var(--muted); margin-top: -8px; }

  .qa-field { display: flex; flex-direction: column; gap: 7px; }

  .qa-lbl { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }

  /* Native selects, restyled rather than rebuilt: a listbox written in
     JavaScript is a keyboard and screen reader problem for no gain, and on a
     phone the system picker is better than anything drawn here. */
  .qa-sel {
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    padding: 13px 34px 13px 12px;
    border: 1px solid #e4e4e4;
    border-radius: 0;
    background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6'%3E%3Cpath d='M1 1l3.5 3.5L8 1' fill='none' stroke='%23111'/%3E%3C/svg%3E") no-repeat right 13px center;
    font-family: inherit;
    font-size: 11px;
    letter-spacing: 0.02em;
    color: #111;
    cursor: pointer;
  }
  .qa-sel:focus { outline: none; border-color: #111; }
  .qa-sel:disabled { color: var(--muted); background-image: none; cursor: default; }

  /* ── CART DRAWER ── */
  .cart-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.15);
    z-index: 200;
  }

  .cart-overlay.open { display: block; }

  .cart-drawer {
    position: fixed;
    top: 0;
    right: -400px;
    width: 360px;
    height: 100vh;
    height: 100dvh;
    background: #fff;
    z-index: 201;
    display: flex;
    flex-direction: column;
    transition: right 0.3s ease;
    padding: 32px 24px;
  }

  .cart-drawer.open { right: 0; }

  .cart-drawer-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 32px;
  }

  .cart-drawer-title {
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  .cart-close {
    font-size: 18px;
    cursor: pointer;
    color: var(--muted);
    background: none;
    border: none;
    line-height: 1;
  }

  .cart-close:hover { color: #111; }

  .cart-items { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 20px; }

  .cart-empty { color: var(--muted); font-size: 11px; padding-top: 8px; }

  .ci {
    display: grid;
    grid-template-columns: 56px 1fr auto;
    gap: 14px;
    align-items: start;
  }

  .ci-img { aspect-ratio: 1; background: #f2f2f2; overflow: hidden; }
  .ci-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .ci-name { font-family: var(--serif); font-size: 12px; }
  .ci-sub { font-size: 10px; color: var(--muted); margin-top: 4px; }
  .ci-remove {
    margin-top: 6px; padding: 0; border: 0; background: none;
    font: inherit; font-size: 10px; letter-spacing: 0.04em; color: var(--muted);
    border-bottom: 1px solid #eee; cursor: pointer; transition: color 0.15s, border-color 0.15s;
  }
  .ci-remove:hover { color: #111; border-color: #111; }
  .ci-price { font-size: 11px; }

  .cart-footer { border-top: 1px solid #f0f0f0; padding-top: 24px; margin-top: 24px; display: flex; flex-direction: column; gap: 16px; }

  .cart-total {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
  }

  .cart-total-lbl { color: var(--muted); }

  .atc {
    background: #111;
    color: #fff;
    border: none;
    padding: 14px 16px;
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 11px;
    letter-spacing: 0.05em;
    cursor: pointer;
    width: 100%;
    transition: opacity 0.15s;
    text-align: center;
  }

  .atc:hover { opacity: 0.75; }
  .atc:disabled { opacity: 0.4; cursor: default; }

  /* ── FOOTER ── */
  footer {
    padding-top: 48px;
    padding-bottom: 48px;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 48px;
    border-top: 1px solid #f0f0f0;
  }

  .ft-logo {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    color: #111;
    margin-bottom: 20px;
  }

  .ft-logo svg { display: block; fill: currentColor; }
  .ft-logo .lk { width: 35.2px; height: 28px; }
  .ft-logo .lw { width: 112px; height: 24px; }

  /* Footer type was #bbb on white, which measures 1.92:1 — the quiet was
     coming from illegibility rather than from restraint. Headings take the
     black and the links take a mid grey at 5.03:1, so the hierarchy is
     carried by weight and case instead of by fading everything out. */
  .ft-addr { font-size: 11px; line-height: 1.9; color: var(--muted); }
  .ft-addr a { color: inherit; transition: color 0.15s; }
  .ft-addr a:hover { color: #111; }
  .ft-city { display: block; margin-top: 14px; }

  /* The logo stands alone in the top row; the Shop and Info columns start
     level with the first address line beside it. 62px of logo plus its
     20px margin. */
  .ft-col { padding-top: 82px; }

  .ft-h {
    font-size: 10px;
    color: #111;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 16px;
  }

  .ft-links { list-style: none; display: flex; flex-direction: column; gap: 12px; }

  .ft-links a { font-size: 11px; color: var(--muted); cursor: pointer; transition: color 0.15s; }
  .ft-links a:hover { color: #111; }

  /* The bottom bar shares the footer's own columns, so the Instagram link
     stands exactly under Shop and the credit under Info's edge, right. */
  .ft-copy {
    grid-column: 1 / -1;
    padding-top: 32px;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 48px;
    font-size: 10px;
    color: var(--muted);
  }
  .ft-copy .ft-credit { justify-self: end; }

  /* ── MENU ── */
  .menu-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding-bottom: var(--head-gap);
  }

  /* The pick-up promise is the section's one operational fact, so it reads
     as a line of its own under the headline rather than a footnote, and it
     stays on phones. */
  .menu-pickup {
    margin: -6px 0 var(--head-gap);
    font-size: 13px;
    line-height: 1.6;
    /* One line on anything wider than a phone; the 52ch measure it had
       broke "Downtown LA" onto a second line on desktop. */
  }
  @media (min-width: 769px) { .menu-pickup { white-space: nowrap; } }

  /* ── DRINK GRID ──
     Four up, every card the same size, the row ending exactly on the section
     gutter. The rail this replaces cut its last card at the edge as a scroll
     affordance; read as a broken grid instead, which is a fair verdict when
     every other block on the page ends flush. */
  .menu-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--card-gap);
  }

  /* Drink cards, leads and grid alike. The shop card language: name on the
     picture, ingredients under it, price at the foot, the order button
     rising on hover. No bean layer to crossfade to, so the photograph holds
     through the hover and only the button rises. */
  .menu-lead {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--card-gap);
    margin-bottom: var(--card-gap);
  }
  /* Square, unlike the 3/4 cards everywhere else: two columns wide, the
     portrait crop would tower. */
  .menu-lead .card-img { aspect-ratio: 1/1; }
  /* On a phone the two leads stack full width; they lead. */
  @media (max-width: 480px) {
    .menu-lead { grid-template-columns: 1fr; }
  }
  /* The card button is there at rest, quietly: white text and a hairline
     on the photograph, no fill. The hover fills it white. Frederik, 23 Sep:
     a visitor should see that a drink or a coffee can be ordered without
     having to find the hover. Drinks first, the coffee cards the same day. */
  .drink-card .card-cta, .shop-card .card-cta {
    opacity: 1; transform: none; pointer-events: auto;
    padding: 10px 12px;
    border: 1px solid rgba(255,255,255,0.7);
    background: transparent;
    color: #fff;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  }
  .drink-card:hover .card-cta, .drink-card .card-cta:hover,
  .shop-card:hover .card-cta, .shop-card .card-cta:hover { background: #fff; color: #111; border-color: #fff; }
  .drink-card .card-cta:disabled, .shop-card .card-cta:disabled { background: transparent; color: rgba(255,255,255,0.7); border-color: rgba(255,255,255,0.35); }
  /* ── MENU MODE ──
     Pick-up ordering lives in Square Online (11 Sep 2026), so the drinks
     read as a menu: the four photographed drinks make a row, as many
     photographs make a two-column grid at every width (Frederik, 11 Sep),
     square like the old two-up leads, and that grid is the section.
     Doubled selector on purpose: .menu-lead has its own phone breakpoint
     later in the file. */
  .drink-card--menu { cursor: default; }
  .menu-pickup a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .menu-pickup a:hover { border-color: #111; }
  .menu-lead.menu-lead--photos { grid-template-columns: repeat(2, 1fr); }
  /* With ordering on, each lead carries a name, the ingredient line, a size,
     a price and a button. Two up on a phone that was a 173px square with the
     text over the drink; one up it reads. Supersedes the two-column-at-every-
     width call of 11 Sep for phones (23 Sep). */
  @media (max-width: 480px) {
    .menu-lead.menu-lead--photos { grid-template-columns: 1fr; }
  }

  /* ── PICK-UP ORDERING (order.js) ──
     The list under the photographs, in sections, each drink with a price
     and an Order button; the panel and the bag borrow the quick add and
     drawer classes. Doubled selectors on purpose against the .menu-grid
     breakpoints later in the file. */
  .menu-grid.menu-grid--list { display: block; }
  .menu-sec { margin-top: 32px; }
  .menu-sec-h { font-family: var(--serif); font-size: 15px; font-weight: 400; margin-bottom: 4px; }
  .menu-row { display: flex; justify-content: space-between; align-items: center; gap: 18px; padding: 12px 0; border-bottom: 1px solid #eee; }
  .menu-row-name { font-family: var(--serif); font-size: 17px; font-weight: 400; line-height: 1.2; }
  .menu-row-ing { margin-top: 3px; font-size: 11px; line-height: 1.6; color: var(--muted); max-width: 40ch; }
  .menu-row-right { display: flex; align-items: center; gap: 16px; white-space: nowrap; }
  .menu-row-price { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; }
  /* Same words and the same case as the button on the photographs. */
  .menu-row-add { padding: 9px 14px; border: 1px solid #111; background: #fff; color: #111; font: inherit; font-size: 11px; letter-spacing: 0.04em; cursor: pointer; transition: background 0.15s, color 0.15s; }
  .menu-row-add:hover { background: #111; color: #fff; }
  .menu-row-add:disabled { border-color: #ddd; color: var(--muted); cursor: default; }
  .menu-bag-link { display: inline-block; margin-left: 12px; padding: 0; border: 0; border-bottom: 1px solid #111; background: none; font: inherit; color: #111; cursor: pointer; }
  /* On a phone the link always wraps to its own line, where the 12px read as
     a stray indent. */
  @media (max-width: 480px) { .menu-bag-link { display: block; width: max-content; margin: 6px 0 0; } }
  .po-many { border: 0; padding: 0; margin: 0; min-width: 0; }
  .po-many .qa-lbl { display: block; margin-bottom: 4px; }
  .po-opt { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid #eee; font-size: 11px; cursor: pointer; }
  .po-opt input { margin: 0; accent-color: #111; }
  .po-opt-price { margin-left: auto; color: var(--muted); font-size: 10px; letter-spacing: 0.04em; }
  .pb-form { display: flex; flex-direction: column; gap: 14px; }
  .pb-form .cart-footer { margin-top: 6px; }
  .pb-note { font-size: 10px; line-height: 1.6; color: var(--muted); margin: 8px 0 12px; }
  .pb-error { font-size: 11px; line-height: 1.6; color: #111; }
  .ci--pickup { grid-template-columns: 1fr auto; }
  @media (max-width: 640px) {
    .menu-row-right { flex-direction: column; align-items: flex-end; gap: 8px; }
  }
  /* The short list as tiles: four across, two on a tablet and a phone, no
     rules between them. Each is the name with a small line-drawn cup to its
     right, its ingredients, size and price, then the button the width of
     the column.
     Doubled selector on purpose against the .menu-grid breakpoints later
     in the file. The ingredient line takes the slack so every button in a
     row sits on the same line. */
  .menu-grid.menu-grid--tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 40px var(--card-gap); margin-top: 28px; }
  /* The full menu on the pick-up page: a section heading, then its tiles. */
  .menu-grid.menu-grid--sections { display: block; }
  .menu-sec .menu-grid.menu-grid--tiles { margin-top: 20px; }
  .menu-sec + .menu-sec { margin-top: 48px; }
  /* ── THE PICK-UP PAGE ──
     A sticky bar of section names under the nav, then each section as a
     list of rows: text left, a 76px thumbnail right, a hairline between
     rows. Two columns from tablet up, one on a phone. The bag is a bar
     along the foot of the screen once it holds anything. */
  .mp-wrap { padding-top: 0; }
  .mp-nav { position: sticky; top: 48px; z-index: 90; background: #fff; border-bottom: 1px solid #eee; }
  .mp-nav-in { display: flex; gap: 22px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .mp-nav-in::-webkit-scrollbar { display: none; }
  .mp-nav a { flex: none; padding: 14px 0 12px; border-bottom: 2px solid transparent; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); white-space: nowrap; transition: color 0.15s, border-color 0.15s; }
  .mp-nav a.is-on, .mp-nav a:hover { color: #111; border-color: #111; }
  .mp-sec { padding-top: 40px; scroll-margin-top: 100px; }
  .mp-h { font-family: var(--serif); font-size: 24px; font-weight: 400; letter-spacing: -0.01em; margin-bottom: 4px; }
  .mp-list { display: grid; grid-template-columns: 1fr; gap: 0; }
  .mp-row { position: relative; display: grid; grid-template-columns: 1fr 76px; gap: 18px; align-items: start; padding: 18px 0; border-bottom: 1px solid #eee; }
  .mp-hit { position: absolute; inset: 0; z-index: 1; }
  .mp-text { min-width: 0; }
  .mp-name { font-family: var(--serif); font-size: 17px; line-height: 1.2; }
  .mp-ing { margin-top: 3px; font-size: 11px; line-height: 1.6; color: var(--muted); }
  .mp-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
  .mp-price { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; line-height: 1.5; }
  .mp-wrap .menu-pickup { margin-top: 18px; }
  .mp-add { position: relative; z-index: 2; flex: none; white-space: nowrap; padding: 9px 12px; border: 1px solid #111; background: #fff; color: #111; font: inherit; font-size: 11px; letter-spacing: 0.04em; cursor: pointer; transition: background 0.15s, color 0.15s; }
  .mp-add:hover { background: #111; color: #fff; }
  .mp-add:disabled { border-color: #ddd; color: #999; background: #fff; cursor: default; }
  .mp-thumb { width: 76px; height: 76px; background: #f4f4f4; overflow: hidden; }
  .mp-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; filter: grayscale(1); }
  .mp-thumb .menu-art { width: 76px; height: 76px; margin: 0; }
  .mp-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 95; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 16px; padding-bottom: calc(12px + env(safe-area-inset-bottom)); background: #111; color: #fff; font-size: 12px; letter-spacing: 0.02em; }
  .mp-bar button { padding: 11px 18px; border: 1px solid #fff; background: #fff; color: #111; font: inherit; font-size: 11px; letter-spacing: 0.04em; cursor: pointer; }
  .mp-wrap:has(.mp-bar:not([hidden])) { padding-bottom: 96px; }
  @media (min-width: 769px) {
    .mp-list { grid-template-columns: 1fr 1fr; column-gap: 48px; }
    .mp-row { grid-template-columns: 1fr 96px; }
    .mp-thumb, .mp-thumb .menu-art { width: 96px; height: 96px; }
    .mp-sec { padding-top: 56px; }
  }
  @media (min-width: 1025px) {
    .mp-bar { left: auto; right: 24px; bottom: 24px; padding: 12px 12px 12px 20px; gap: 24px; }
  }
  @media (hover: none) { .mp-add { min-height: 44px; } }
  /* The second pair of photographs, under the grid. */
  .menu-lead--tail { margin-top: 40px; margin-bottom: 0; }
  .menu-tile { display: flex; flex-direction: column; }
  /* Name left, the drawing right on the same line, its rim level with the
     name's cap height; all vessels stand on one baseline in the box, so a
     tall glass rises above a short cup rather than dropping below it. */
  .menu-tile-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; }
  .menu-art { display: block; flex: none; width: 40px; height: 40px; margin: -20px -6px -4px 0; }
  .menu-tile .menu-row-ing { flex: 1; margin-top: 4px; max-width: none; }
  .menu-tile .menu-row-price { align-items: flex-start; margin: 14px 0 10px; }
  .menu-tile .menu-row-add { width: 100%; padding: 12px 8px; }
  @media (max-width: 768px) { .menu-grid.menu-grid--tiles { grid-template-columns: repeat(2, 1fr); gap: 32px var(--card-gap); } }
  @media (max-width: 480px) { .menu-grid.menu-grid--tiles { gap: 28px var(--card-gap); } }
  .drink-ing {
    margin-top: 6px;
    font-size: 11px;
    letter-spacing: 0.03em;
    line-height: 1.6;
    max-width: 44ch;
    opacity: 0.85;
  }
  /* Grid cards carry a smaller ingredient line than the leads. */
  .menu-grid .drink-ing { font-size: 10px; margin-top: 4px; }

  /* The drink hover: a harder push in and the colour drained, so the grid
     reads documentary the moment a card is considered. */
  .drink-card:hover .card-img img { transform: scale(1.22); filter: grayscale(1); }

  /* loading skeleton */
  .skeleton {
    background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: shimmer 1.2s infinite;
    border-radius: 2px;
  }

  @keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

  /* ── STORY ──
     Facts left, one square picture right. The two founder frames that were
     here moved to the About page: on the homepage this block is a summary
     with a way in, not a gallery. */
  .story-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--card-gap);
    align-items: center;
  }

  /* ── RESPONSIVE ──
     1024 tablet, 768 phone landscape, 480 phone. Gutters step 32 → 24 → 16.
     Below 768 the nav collapses to a sheet, and every grid on the page runs
     two up: shop, merch and drinks alike. Eight products stacked one to a row
     is 3,000px of scrolling and no overview at all; two up you can see the
     range. The card contents are what had to give — the buy label shortens,
     the size and price stack — not the column count. */

  @media (max-width: 1024px) {
    :root { --section-gap: 104px; --head-gap: 22px; --card-gap: 14px; }
    nav, .hero, .shop, footer { padding-left: 24px; padding-right: 24px; }
    .grid { grid-template-columns: repeat(3, 1fr); }
    .menu-grid { grid-template-columns: repeat(3, 1fr); }

    footer { grid-template-columns: 1fr 1fr; gap: 36px; }
  }

  @media (max-width: 768px) {
    :root { --section-gap: 76px; --head-gap: 18px; --card-gap: 10px; }
    nav, .hero, .shop, footer { padding-left: 16px; padding-right: 16px; }
    /* the links leave the bar and become a sheet */
    .nav-toggle { display: flex; }

    .nav-r {
      position: fixed;
      left: 0; right: 0; top: 48px; bottom: 0;
      background: #fff;
      flex-direction: column;
      justify-content: flex-start;
      align-items: stretch;
      gap: 0;
      padding: 4px 16px 40px;
      overflow-y: auto;
      opacity: 0;
      visibility: hidden;
      transform: translateY(-8px);
      transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
      z-index: 95;
    }

    nav.open .nav-r { opacity: 1; visibility: visible; transform: none; }

    .nav-r a {
      font-family: var(--serif);
      font-size: 22px;
      letter-spacing: -0.01em;
      padding: 18px 0;
      border-bottom: 1px solid #f0f0f0;
    }

    .nav-r a:last-child { border-bottom: 0; }

    .hero { padding-bottom: var(--section-gap); }
    .hero-img { aspect-ratio: 3/2; margin-bottom: 14px; }
    .hero-meta { flex-direction: column; align-items: flex-start; gap: 14px; }
    .hero-sub { text-align: left; padding-bottom: 0; }
    .hero-hours { text-align: left; align-self: flex-start; }
    .shop { padding-bottom: var(--section-gap); }
    .grid { grid-template-columns: repeat(2, 1fr); }
    .menu-grid { grid-template-columns: repeat(2, 1fr); }

    /* stacked, picture first: the section should open with an image like the
       ones above it, and the facts read better under it than over it */
    .story-split { grid-template-columns: 1fr; gap: 18px; }
    .story-img, .story-split .abrazo-slides { order: -1; }
    /* Doubled selector on purpose: the base --wide rule sits later in the
       file, so the mobile override needs the extra weight to win. */
    .story-split.story-split--wide { grid-template-columns: 1fr; }

    .menu-head { padding-bottom: var(--head-gap); }
    .pdp-overlay { padding: 12px; }
    .qa-modal { max-width: 460px; }
    .cart-drawer { width: 100%; right: -100%; padding: 24px 16px; }
    /* On a phone the drawer scrolls as one piece. The desktop drawer pins its
       footer and scrolls the item list, which on a short screen, or with the
       keyboard up, crushed the list to nothing under the pick-up form. */
    .cart-drawer { overflow-y: auto; }
    .cart-items { flex: 1 0 auto; overflow: visible; padding-bottom: 24px; }
    footer { padding-top: 36px; gap: 28px; }
    .ft-copy { flex-direction: column; gap: 8px; padding-top: 24px; }
  }

  @media (max-width: 480px) {
    :root { --section-gap: 64px; --head-gap: 16px; --card-gap: 8px; }
    nav, .hero, .shop, footer { padding-left: 14px; padding-right: 14px; }
    .logo { gap: 7px; }
    .logo .lk { width: 20.1px; height: 16px; }
    .logo .lw { width: 60.7px; height: 13px; }
    .shop-head { padding-bottom: var(--head-gap); }
    .menu-grid { grid-template-columns: repeat(2, 1fr); }

    /* Shop card at two up. The face has to carry a name, a size, a price and
       a button in about 145px of usable width. */
    .card-face { padding: 11px; }
    .card-blend { font-size: 16px; }
    .card-meta { flex-direction: column; align-items: flex-start; gap: 2px; }
    .card-cta { font-size: 11px; padding: 12px 8px; margin-top: 9px; }
    .cta-full { display: none; }
    .cta-tight { display: inline; }

    /* the panel takes the width of the phone, less a hairline of backdrop */
    .pdp-overlay { padding: 10px; }
    .qa-modal { max-width: none; }
    .qa-panel { padding: 16px 16px 20px; gap: 12px; }
    .qa-name { font-size: 23px; }

    /* ── FOOTER ON A PHONE ──
       Three stacked lists of 11px grey ran 728px, most of a screen, with
       nothing to hold the eye and no target a thumb could hit. Same links,
       given a shape: brand band, then Shop across the full width with its
       products two up, then Merch and Info side by side. Hairlines between
       the bands rather than gaps, so it reads as sections rather than drift. */
    footer { grid-template-columns: 1fr 1fr; column-gap: 18px; row-gap: 0; padding-top: 40px; padding-bottom: 40px; }

    .ft-brand { grid-column: 1 / -1; padding-bottom: 26px; border-bottom: 1px solid #f0f0f0; }
    .ft-logo { margin-bottom: 16px; }

    .ft-col--shop { grid-column: 1 / -1; padding: 22px 0; border-bottom: 1px solid #f0f0f0; }
    /* Multicol rather than a two-column grid: it runs down the first column
       and then across, which is how a list is read, and it balances itself as
       the catalogue grows or shrinks. A grid would go across-then-down and
       would need the product count hard-coded. */
    /* Three links stack; the two-column split was for a full product list. */
    .ft-col--shop .ft-links li { break-inside: avoid; }
    .ft-col--info { padding-top: 22px; }

    .ft-h { margin-bottom: 2px; }
    .ft-links { gap: 0; }
    .ft-links a { font-size: 13px; }
    .ft-copy { margin-top: 24px; padding-top: 20px; border-top: 1px solid #f0f0f0; }
  }

  .story-facts { display: flex; flex-direction: column; gap: 26px; }
  .story-fact-h {
    font-family: var(--serif);
    font-size: 15px;
    font-weight: 400; /* the fact heads are h3 now; no browser bold */
    margin-bottom: 6px;
  }
  .story-fact p { font-size: 12px; line-height: 1.85; color: var(--muted); max-width: 42ch; }
  .story-more {
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border-bottom: 1px solid #eee;
    align-self: flex-start;
    transition: border-color 0.15s;
  }
  .story-more:hover { border-color: #111; }

  /* ── ABRAZO ──
     Same split as the story block, but the picture takes two thirds: a night
     reads as a room, not a thumbnail. One 3/2 frame running a crossfade of
     five photographs, arrows in the corner, same grayscale as every
     photograph on this page. */
  .story-split--wide { grid-template-columns: 1fr 2fr; }
  .abrazo-slides {
    position: relative;
    aspect-ratio: 3/2;
    overflow: hidden;
    background: #f7f7f7;
  }
  .abrazo-slides .slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 1.1s ease;
  }
  .abrazo-slides .slide.on { opacity: 1; }
  .abrazo-slides .slide img {
    width: 100%; height: 100%; object-fit: cover; display: block;
  }
  /* The homepage strip runs black and white; Arrangements keeps the colour.
     A class on the container, not two copies of the slider. */
  .abrazo-slides--bw .slide img { filter: grayscale(1); }
  .abrazo-arrows { position: absolute; right: 0; bottom: 0; display: flex; z-index: 2; }
  .abrazo-arrows button {
    width: 36px; height: 36px;
    border: 0; padding: 0;
    background: #fff; color: #111;
    font: 14px/1 var(--sans, 'Helvetica Neue', Helvetica, Arial, sans-serif);
    cursor: pointer;
  }
  .abrazo-arrows button:hover { background: #111; color: #fff; }
  @media (prefers-reduced-motion: reduce) {
    .abrazo-slides .slide { transition: none; }
  }

  .story-img { aspect-ratio: 1/1; overflow: hidden; background: #f7f7f7; }
  .story-img img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    /* black and white, as a filter: the colour original stays in the repo */
    filter: grayscale(1);
  }

  /* ── TOUCH ──
     There is no hover on a phone, so anything that only appears on hover would
     never appear at all. The buy button and the photo credits are shown
     outright, and the bean layer is dropped rather than downloaded to sit
     invisible behind the packshot. */
  @media (hover: none) {
    .card-cta { opacity: 1; transform: none; pointer-events: auto; min-height: 44px; }
    .menu-row-add { min-height: 44px; }
    .shop-card .card-alt { display: none; }

    /* A footer link was a 24x12 target. A thumb needs 44px, and that is a
       fact about fingers rather than about viewport width, so it hangs off
       the touch query rather than off a breakpoint. */
    .ft-links a { display: flex; align-items: center; min-height: 44px; }
    /* block, not inline-block: inline-block let the phone number ride up onto
       the end of the address line. width:max-content keeps the tap box on the
       text rather than spanning the column. */
    .ft-addr a { display: block; width: max-content; max-width: 100%; padding: 6px 0; }

    /* Text links measured 12 to 17px tall under a thumb. Padding grows the
       tap box to about 44px and the negative margin gives the space back,
       so nothing moves. */
    .hero-sub a, .visit-info a, .head-link, .story-more, .arr-cta a,
    .arr-note a, .detail-val a, .ft-copy a, .pd-crumb a, .menu-pickup a {
      display: inline-block; padding: 15px 0; margin: -15px 0;
    }
    /* A 44px tap box that reaches the screen edge, with the lines drawn at
       the same inset as the logo on the left (phone feedback, 30 Sep). */
    .nav-toggle { width: 44px; height: 44px; box-sizing: border-box; margin-right: -14px; padding-right: 14px; }
    .qa-x { width: 44px; height: 44px; top: 4px; right: 4px; }
    .cart-close { padding: 12px; margin: -12px; }
    .abrazo-arrows button { width: 44px; height: 44px; }
    .qa-back, .qa-details { display: inline-block; padding: 12px 0; margin: -12px 0; }
    /* The 44px close sits 4px in from the modal's edge; Details ends at the
       panel's 16px padding and was 32px under it, so a tap on Details closed
       the panel. The right margin keeps the link clear of the button. */
    .qa-details { margin-right: 40px; }
    .ci-remove { display: inline-block; padding: 12px 0; margin: -6px 0 -12px; }
  }

  /* ── SHOP PAGE ──
     The homepage sells a selection from a grid that has to sit between a hero
     and a drink menu. This page has nothing else to do, so the cards get their
     type beneath the picture instead of over it: on a page that is only
     shopping, the name, the price and the button have to be readable at a
     glance, and white type on a scrim is a mood rather than a price tag. */
  .sp-top { padding-top: 44px; padding-bottom: 52px; }
  .sp-title {
    font-family: var(--serif);
    font-size: clamp(40px, 6vw, 86px);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.025em;
  }
  .sp-intro { font-size: 12px; line-height: 1.85; color: var(--muted); max-width: 46ch; margin-top: 18px; }

  /* Questions under the grid: the question in the serif on the left, the
     answer on the right, a hairline between pairs, the same split as the
     Arrangements blocks. One column on a phone. */
  .faq { border-top: 1px solid #eee; }
  .faq-item { display: grid; grid-template-columns: 1fr 2fr; gap: 32px; padding: 22px 0; border-bottom: 1px solid #eee; }
  .faq-item dt { font-family: var(--serif); font-size: clamp(18px, 1.6vw, 22px); font-weight: 400; line-height: 1.2; letter-spacing: -0.01em; }
  .faq-item dd { max-width: 54ch; font-size: 13px; line-height: 1.9; }
  .faq-item dd a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .faq-item dd a:hover { border-color: #111; }

  /* Four up, like the grid on the homepage: five coffees and four merch
     items is a catalogue, and a catalogue wants to be seen at once. The
     sections that hold three cards run three up so neither ends on an orphan. */
  .sp-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--card-gap); }

  .sp-card { display: flex; flex-direction: column; cursor: default; }
  .sp-hit { display: block; color: inherit; }
  /* 4/5 against sources that are 3/4 and 4/5: a square would cut a
     quarter off a standing bag, and 3/4 towers at this width. */
  .sp-card .card-img { aspect-ratio: 4/5; }

  /* ── ONE HOVER ──
     Every card on this page answers the same way: the picture eases up a
     little, nothing else. The coffee used to crossfade to a bean shot while
     the merch and the proposals did nothing at all, which read as three
     different kinds of card rather than one catalogue. The bean swap stays on
     the homepage, where it is one device on one grid. */
  .sp-card .card-img img { transition: transform 0.7s cubic-bezier(0.22,1,0.36,1), opacity 0.4s ease; }
  /* The shop page's cards swap to the bean on hover, the way the homepage
     cards do (30 Sep 2026); the zoom stays for the bag underneath. */
  .sp-card:hover .card-img img { transform: scale(1.04); }
  .sp-card:hover .card-base { opacity: 0; }
  .sp-card:hover .card-alt { opacity: 1; }
  .sp-name { font-family: var(--serif); font-size: 18px; line-height: 1.2; margin-top: 14px; }
  .sp-sub { font-size: 11px; line-height: 1.7; color: var(--muted); margin-top: 6px; max-width: 36ch; }
  .sp-foot {
    display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
    font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
    margin-top: 12px; padding-top: 11px; border-top: 1px solid #f0f0f0;
  }
  .sp-foot .sp-lead { color: #111; }
  /* Shopify carries a line for two of the five coffees and nothing for the
     rest, so the copy above the rule is ragged by nature. The rule and the
     button are pushed to the foot instead, and a row ends on two straight
     lines rather than on five different ones. */
  .sp-card .sp-foot { margin-top: auto; }
  .sp-add {
    margin-top: 12px; width: 100%; padding: 13px;
    border: 1px solid #111; background: #fff; color: #111;
    font-family: inherit; font-size: 11px; letter-spacing: 0.05em;
    cursor: pointer; transition: background 0.15s, color 0.15s;
  }
  .sp-add:hover { background: #111; color: #fff; }
  .sp-add:disabled { border-color: #ececec; color: var(--muted); background: #fff; cursor: default; }

  .sp-note { font-size: 11px; line-height: 1.8; color: var(--muted); max-width: 46ch; padding-bottom: var(--head-gap); }

  @media (max-width: 1024px) {
    .sp-grid { grid-template-columns: repeat(3, 1fr); }
    .sp-name { font-size: 16px; }
  }

  @media (max-width: 768px) {
    .sp-top { padding-top: 28px; padding-bottom: 36px; }
    .faq-item { grid-template-columns: 1fr; gap: 8px; padding: 18px 0; }
    /* Row gap wider than the column gap, so a button reads as the foot of
       the card above it, not the head of the one below (phone feedback,
       30 Sep). */
    .sp-grid { grid-template-columns: repeat(2, 1fr); row-gap: 44px; }
    .sp-sub { display: none; }
    .sp-name { font-size: 15px; margin-top: 10px; }
    .sp-foot { flex-direction: column; gap: 3px; margin-top: 9px; padding-top: 9px; }
  }

  @media (max-width: 480px) {
    .sp-name { font-size: 13px; }
    .sp-add { padding: 12px 8px; }
  }

  /* ── PRODUCT PAGE ──
     Where See Full Details goes. The buy controls are the same two selects and
     the same dark button as the quick add panel, deliberately: the panel is a
     shortcut to this page, so it should not be a different transaction. */
  .pd-wrap { padding-top: 26px; padding-bottom: var(--section-gap); }
  .pd-crumb { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 24px; }
  .pd-crumb a { transition: color 0.15s; }
  .pd-crumb a:hover { color: #111; }

  .pd-split { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(32px, 5vw, 72px); align-items: start; }
  .pd-main { aspect-ratio: 1/1; background: #f7f7f7; overflow: hidden; }
  .pd-main img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .pd-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--card-gap); margin-top: var(--card-gap); }
  .pd-thumb { aspect-ratio: 1/1; overflow: hidden; background: #f7f7f7; border: 0; padding: 0; cursor: pointer; }
  .pd-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: opacity 0.2s; }
  .pd-thumb:hover img { opacity: 0.78; }

  .pd-detail { display: flex; flex-direction: column; gap: 16px; max-width: 440px; }
  .pd-name { font-family: var(--serif); font-size: clamp(32px, 4vw, 54px); font-weight: 400; line-height: 1.04; letter-spacing: -0.02em; }
  .pd-price { font-size: 12px; }
  .pd-desc { font-size: 12px; line-height: 1.9; color: var(--muted); }
  .pd-sizes { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
  .pd-ship { font-size: 11px; line-height: 1.8; color: var(--muted); max-width: 44ch; }
  .pd-ship a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .pd-ship a:hover { border-color: #111; }
  .pd-missing { padding: 60px 0 100px; }
  /* three coffees under the one being read, so the row fills */
  #more-grid { grid-template-columns: repeat(3, 1fr); }
  .pd-missing .pd-name { margin-bottom: 16px; }

  @media (max-width: 768px) {
    .pd-split { grid-template-columns: 1fr; gap: 24px; }
    .pd-detail { max-width: none; }
    .pd-thumbs { grid-template-columns: repeat(4, 1fr); }
  }

  /* ── VISIT / ABOUT / ARRANGEMENTS ──
     The hero with the page name under it, the details grid, the photo grids
     and the arrangement blocks. Shared by the three pages that tell rather
     than sell. */
  .visit-hero { padding: 24px 32px 0; }
  .visit-hero-img { width: 100%; aspect-ratio: 16/7; overflow: hidden; background: #f2f2f2; }
  .visit-hero-img img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center 30%;
    display: block;
  }
  /* The About hero runs black and white; Visit and Arrangements keep colour. */
  .visit-hero-img--bw img { filter: grayscale(1); }
  .visit-hero-meta { display: flex; justify-content: space-between; align-items: flex-end; padding: 16px 0 48px; }
  .visit-title {
    font-family: var(--serif);
    font-size: clamp(38px, 5.4vw, 76px);
    font-weight: 400;
    letter-spacing: -0.015em;
    line-height: 0.94;
  }
  .visit-info { text-align: right; display: flex; flex-direction: column; gap: 6px; }
  .visit-info span { font-size: 11px; color: var(--muted); display: block; }
  .visit-info a { font-size: 11px; color: #111; transition: color 0.15s; }
  .visit-info a:hover { color: var(--muted); }

  .details {
    padding-top: 32px;
    padding-bottom: var(--section-gap);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--card-gap);
    border-top: 1px solid #f0f0f0;
  }
  .detail-block { display: flex; flex-direction: column; gap: 8px; }
  .city {
    grid-column: 1 / -1;
    font-family: var(--serif);
    font-size: clamp(16px, 1.4vw, 20px);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 10px;
  }
  .details + .details { border-top: 0; padding-top: 0; }
  .detail-lbl { font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--muted); }
  .detail-val { font-size: 11px; color: #111; line-height: 1.8; }
  .detail-val a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .detail-val a:hover { border-color: #111; }

  .photo-grid { padding-top: 0; padding-bottom: var(--section-gap); display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--card-gap); }
  .photo-grid .wide { grid-column: span 2; }
  .photo-cell { overflow: hidden; background: #f7f7f7; }
  .photo-cell img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: center;
    display: block;
    transition: transform 0.6s ease;
    aspect-ratio: 3/4;
  }
  .photo-cell.wide img { aspect-ratio: 16/10; }
  .photo-cell:hover img { transform: scale(1.03); }

  /* The same page ceiling as the selling pages. */
  .visit-hero, .details, .photo-grid, .arr-intro, .arr-rule, .arr-block, .arr-cta, .arr-pair {
    padding-left: max(32px, calc((100% - 1600px) / 2));
    padding-right: max(32px, calc((100% - 1600px) / 2));
  }

  .arr-intro { padding-top: 0; padding-bottom: var(--section-gap); max-width: 46ch; font-size: 13px; line-height: 1.9; color: #111; }
  .arr-block { padding-top: 0; padding-bottom: var(--section-gap); display: grid; grid-template-columns: 1fr 2fr; gap: 32px; align-items: start; }
  /* A link to a section lands with its heading clear of the sticky nav. */
  [id] { scroll-margin-top: 64px; }
  .arr-h { font-family: var(--serif); font-size: clamp(20px, 2.1vw, 28px); font-weight: 400; letter-spacing: -0.01em; line-height: 1.1; }
  .arr-body { max-width: 54ch; font-size: 13px; line-height: 1.9; color: #111; }
  /* A block with photographs: the text on the left in its measure, the
     photographs beside it on the right, stacked, square. On a phone the
     photographs follow the text. */
  .arr-body:has(> .arr-media) { max-width: none; display: grid; grid-template-columns: minmax(0, 54ch) minmax(0, 1fr); gap: 32px; align-items: start; }
  .arr-media .arr-img { margin-top: 0; aspect-ratio: 1/1; }
  .arr-media .arr-img + .arr-img { margin-top: var(--card-gap); }
  .arr-body p + p { margin-top: 14px; }
  .arr-body .arr-note { color: var(--muted); font-size: 11px; line-height: 1.8; }
  /* ── WHOLESALE FORM ──
     The quick add panel's field, label and select, plus a text input in the
     same measure. Two columns for the short answers, one for the long. */
  .ws-form { margin-top: 24px; display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
  .ws-wide { grid-column: 1 / -1; }
  .ws-in {
    width: 100%;
    padding: 13px 12px;
    border: 1px solid #e4e4e4;
    border-radius: 0;
    background: #fff;
    font-family: inherit;
    font-size: 11px;
    color: #111;
  }
  .ws-in::placeholder { color: #b5b5b5; }
  .ws-in:focus { outline: none; border-color: #111; }
  textarea.ws-in { resize: vertical; line-height: 1.6; min-height: 96px; }
  .ws-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
  .ws-note { grid-column: 1 / -1; font-size: 11px; line-height: 1.8; color: var(--muted); }
  .ws-done { margin-top: 24px; padding-top: 18px; border-top: 1px solid #eee; }
  .ws-done:focus { outline: none; }
  @media (max-width: 480px) { .ws-form { grid-template-columns: 1fr; } }

  .arr-img { margin-top: 24px; aspect-ratio: 3/2; overflow: hidden; background: #f7f7f7; }
  .arr-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .arr-rule { height: 1px; background: #f0f0f0; margin: 0 0 56px; }
  .abrazo-copy { margin-top: 18px; }

  .arr-pair { padding-bottom: var(--section-gap); }
  .arr-pair-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--card-gap); }
  .arr-pair-img { aspect-ratio: 1/1; overflow: hidden; background: #f7f7f7; }
  .arr-pair-img img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    filter: grayscale(1);
  }

  .arr-cta { padding-top: 0; padding-bottom: var(--section-gap); display: flex; flex-wrap: wrap; gap: 10px 28px; align-items: baseline; font-size: 13px; }
  .arr-cta a { border-bottom: 1px solid #eee; transition: border-color 0.15s; }
  .arr-cta a:hover { border-color: #111; }
  .arr-cta-right { margin-left: auto; }

  @media (max-width: 1024px) {
    .visit-hero, .details, .photo-grid, .arr-intro, .arr-block, .arr-cta, .arr-pair { padding-left: 24px; padding-right: 24px; }
    .arr-rule { margin-left: 24px; margin-right: 24px; }
    .details { grid-template-columns: repeat(2, 1fr); row-gap: 28px; }
  }
  @media (max-width: 768px) {
    .visit-hero, .details, .photo-grid, .arr-intro, .arr-block, .arr-cta, .arr-pair { padding-left: 16px; padding-right: 16px; }
    .arr-rule { margin-left: 16px; margin-right: 16px; }
    .visit-hero-img { aspect-ratio: 3/2; }
    .visit-hero-meta { flex-direction: column; align-items: flex-start; gap: 14px; padding: 14px 0 36px; }
    .visit-info { text-align: left; }
    .details { padding-bottom: var(--section-gap); }
    .photo-grid { grid-template-columns: repeat(2, 1fr); padding-bottom: var(--section-gap); }
    .photo-grid .wide { grid-column: span 1; }
    .photo-cell.wide img { aspect-ratio: 3/4; }
    .arr-block { grid-template-columns: 1fr; gap: 12px; }
    .arr-body:has(> .arr-media) { grid-template-columns: 1fr; gap: 24px; }
  }
  @media (max-width: 480px) {
    .visit-hero, .details, .photo-grid, .arr-intro, .arr-block, .arr-cta, .arr-pair { padding-left: 14px; padding-right: 14px; }
    .arr-rule { margin-left: 14px; margin-right: 14px; }
    .details { grid-template-columns: 1fr; }
  }

  /* Labels, last in the file on purpose: the desktop sizes it overrides
     sit above it, and equal specificity goes to the later rule.
     Labels, prices and the footer sit at 9 and 10px in the desktop system.
     On a phone that is under the size a thumb-length away reads well, so
     they come up to 11px there; the letterspacing keeps the register. */
  @media (max-width: 480px) {
    .card-meta, .sp-foot, .ft-h, .ft-copy, .qa-lbl, .pd-crumb, .pd-sizes,
    .head-link, .qa-back, .detail-lbl, .ci-sub, .ci-remove { font-size: 11px; }
  }

  /* Form controls, last in the file on purpose, after the .ws-in rule they
     override. iPhone Safari zooms the page when a field under 16px takes
     focus and does not zoom back, so on a touch screen every select and
     input comes up to 16px; the labels around them keep the 11px register. */
  @media (hover: none) {
    .qa-sel, .ws-in { font-size: 16px; }
  }
