/* ==========================================================================
   Peak Seafood — style.css

   One stylesheet for every page that links it: the public pages (/, /products/,
   /contact/), the buyer pages (/live-list/, /trade/, /orders/), the legal pages,
   404, and the desk pages (which load admin.css after this file and override
   parts of it under body.admin-app).

   Sections
     1. Tokens            approved public palette + the legacy token names the
                          app pages and their inline <style> blocks still read
     2. Fonts             Arial/Helvetica for text; one self-hosted Mono face
                          for .mono and tabular figures
     3. Shell             resets, skip link, masthead, main navigation, footer,
                          and the public components shared by more than one page
     4. Public pages      This week, Products, Contact
     5. App components    layout, type, forms, buttons, tables, cards, rows,
                          documents (selector names are a contract with the
                          buyer and desk pages; keep them)
     6. Responsive        900 / 760 / 620 / 350
     7. Print
   ========================================================================== */


/* ==========================================================================
   1. Tokens
   ========================================================================== */
:root {
  /* approved public palette */
  --navy: #123543;
  --navy-deep: #0d2833;
  --red: #a63c26;
  --paper: #f4f0e7;
  --white: #fffdf8;
  --ink: #153641;
  --muted: #586568;
  --line: #d5d4c9;
  --ice: #eae7dc;
  --green: #275e47;
  /* Product condition bands: distinct, readable steps above the white rows. */
  --group-live: #b9cec0;
  --group-fresh: #c1cac6;
  --group-frozen: #bcccd8;
  --group-other: #cfcabc;

  /* legacy names, remapped to the palette above. The app pages and the inline
     <style> blocks in desk/buy and desk/sheet read these; keep the names. */
  --card: #fffefa;
  --cream: #e9efee;
  --steel: #52616a;
  --rule: #d4dad8;
  /* The row hairlines were 1.06:1 on paper — a line nobody could see. This is
     1.64:1 on --paper and 1.83:1 on --white: still quiet, but present. */
  --edge: #b7c0bb;
  --rule2: #e6ebe9;
  --harbor: #153c50;
  --harbor-deep: #102e3e;
  --harbor-tint: #e9efee;

  /* spacing scale */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 18px;
  --s5: 28px;
  --s6: 44px;
  --s7: 68px;

  /* font stacks */
  --sans: Plex, 'IBM Plex Sans', Arial, Helvetica, sans-serif;
  --title: Georgia, 'Times New Roman', serif;
  --mono: Mono, "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace;
}


/* ==========================================================================
   2. Fonts
   Text is Arial/Helvetica and needs no font file. Mono (IBM Plex Mono) is
   copied to /fonts/ by the build for the .mono class and tabular figures; when
   the file is absent locally the fallback stack shows, which is expected.
   ========================================================================== */
/* IBM Plex Sans is the approved interface face and was already being built and
   shipped as /fonts/sans.woff2 -- it was simply never referenced. The 600 is now
   built too, so the 600-weight list names are a real cut rather than a synthetic
   bold. Georgia carries the editorial headings; it is a system face, so there is
   nothing to load. */
@font-face { font-family: Plex; src: url(/fonts/sans.woff2) format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: Plex; src: url(/fonts/sans-600.woff2) format('woff2'); font-weight: 600; font-display: swap; }
@font-face { font-family: Mono; src: url(/fonts/mono.woff2) format('woff2'); font-weight: 400; font-display: swap; }
@font-face { font-family: Mono; src: url(/fonts/mono-bold.woff2) format('woff2'); font-weight: 700; font-display: swap; }


/* ==========================================================================
   3. Shell
   ========================================================================== */

/* --- resets --- */
* { box-sizing: border-box; }
html { scroll-padding-top: 76px; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
a, button, input { -webkit-tap-highlight-color: transparent; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid #d37423;
  outline-offset: 4px;
}
button, a { touch-action: manipulation; }
img { max-width: 100%; display: block; }
svg { max-width: 100%; }
h1, h2, h3, p, figure { margin: 0; }
h1, h2, h3 { text-wrap: balance; }
h1 { font-size: clamp(28px, 2.4vw, 38px); line-height: 1.02; font-weight: 800; letter-spacing: -.045em; }
h2 { font-size: 25px; line-height: 1.15; letter-spacing: -.025em; }
h3 { font-size: 18px; line-height: 1.25; letter-spacing: -.01em; }
[hidden] { display: none !important; }

.shell { width: min(1400px, calc(100% - 64px)); margin-inline: auto; }
main { flex: 1 0 auto; min-height: 60vh; padding-bottom: 64px; }
main:focus { outline: none; }

/* --- skip link --- */
.skip { position: absolute; top: -100px; left: 12px; background: var(--white); padding: 12px; z-index: 10; }
.skip:focus { top: 8px; }

/* --- masthead: header.site.masthead > .shell.masthead-inner --- */
.topbar { position: sticky; top: 0; z-index: 6; }
.admin-app .topbar { position: static; }
.masthead { background: var(--white); }
/* 56px is the floor: the brand lockup is 56px tall. The old 74px came from the
   two-line descriptor that used to sit beside it. */
.masthead-inner { min-height: 56px; display: flex; align-items: center; gap: 36px; }

/* One image, sized by WIDTH. The blue lockup is the horizontal one-line mark:
   swimming fish, PEAK, SEAFOOD, 3.4:1. The stacked mark it replaced was 2.29:1
   and had to be pinned to a 72px height to keep SEAFOOD above nine pixels;
   this one puts the letters on one line, so width governs and the height
   follows. The widths live in the blue block at the end of this file. */
.brand { display: flex; align-items: center; flex-shrink: 0; }
.brand .headlogo { display: block; width: 100%; height: auto; }

.masthead-note { font-size: 13px; line-height: 1.35; }
.masthead-note a { font-weight: 700; font-size: 15px; letter-spacing: -.01em; }
.masthead-note a:hover { color: var(--red); }
.masthead-note span { display: block; font-weight: normal; color: var(--muted); font-size: 12px; }

/* .headright holds the account nav (empty until nav.js adds Orders / Desk for a
   signed-in buyer) and the Sign in button, which nav.js swaps for a.headtel
   "Sign out". Keep the bare nav and the a.btn inside .headright. */
.headright { margin-left: auto; display: flex; align-items: center; gap: 20px; flex-shrink: 0; }
.account-nav { display: flex; align-items: center; gap: 16px; }
.account-nav:empty { display: none; }
.account-nav a, .headright .headtel {
  font-family: var(--sans);
  font-size: 13px;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 4px;
  padding-block: 10px;
  white-space: nowrap;
}
.account-nav a:hover, .headright .headtel:hover { color: var(--ink); }
.account-nav a.on { color: var(--ink); font-weight: 700; }

/* .signin also carries .btn (nav.js hook); the masthead scope keeps the red
   button ahead of the navy .btn rules in section 5. */
.masthead .signin {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  background: var(--red);
  color: #fff;
  border: 0;
  padding: 12px 19px;
  min-height: 46px;
  font-weight: bold;
  font-size: 14px;
  line-height: 1.2;
}
.masthead .signin:hover, .button:hover { background: #8f2d20; }

/* --- main navigation: .nav-band > nav.shell.navigation --- */
/* The band sits outside header.site so "header.site nav" still means the account
   nav. Desk pages hide the whole public shell. */
.nav-band { background: var(--navy-deep); box-shadow: 0 2px 0 #102c3b20; overflow: hidden; overflow: clip; }
.admin-app .nav-band { display: none !important; }
.navigation { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.navigation a {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 44px;
  color: #e4edee;
  font-weight: 600;
  font-size: 14px;
  border-inline-start: 1px solid #ffffff18;
  position: relative;
}
.navigation a:first-child::before,
.navigation a:last-child::before {
  content: ""; position: absolute; top: 0; bottom: 0;
  width: 100vw; background: inherit;
}
.navigation a:first-child::before { right: 100%; }
.navigation a:last-child::before { left: 100%; }
/* the outer dividers would otherwise float a stub's width in from each edge */
.navigation a:first-child { border-inline-start: 0; }
.navigation a:hover { background: #ffffff0d; }
.navigation a:focus-visible { outline-offset: -3px; }
/* stamp.cjs marks the current page with aria-current="page" (or class="on" on an
   older header without data-nav hooks); both get the same treatment. */
.navigation a[aria-current=page], .navigation a.on {
  background: var(--paper); color: var(--navy-deep);
  border-inline-start-color: transparent;
}
.navigation a[aria-current=page] + a { border-inline-start-color: transparent; }
.navigation a[aria-current=page]:hover, .navigation a.on:hover { background: var(--paper); }
.navigation a[aria-current=page]:after, .navigation a.on:after {
  content: "";
  position: absolute;
  bottom: 0;
  height: 4px;
  left: 0;
  right: 0;
  background: #d25c43;
}
.navigation a:first-child[aria-current=page]:after, .navigation a:first-child.on:after { left: -100vw; }
.navigation a:last-child[aria-current=page]:after, .navigation a:last-child.on:after { right: -100vw; }

/* --- footer: footer.site > .shell.footer-inner --- */
footer { background: var(--navy-deep); color: var(--white); }
.footer-inner { display: flex; align-items: center; gap: 32px; padding-block: 30px; }
.footer-brand { display: flex; gap: 16px; align-items: center; margin-right: auto; }
/* The approved footer treatment: the full-colour seal on a warm ivory circular
   field against the navy: the old seal was dark linework and vanished straight
   onto navy, so it was given one.

   The reverse seal needs no disc. Cream linework and cream arc type ARE the
   artwork, and they are drawn for a dark ground, so it goes on the navy
   directly. The ivory circle, the border-radius and the padding are gone.

   The three-summit circle is a <picture> now and the blue block at the end of
   this file gives it its 200/180px width, its square aspect and the
   border-radius that clips its painted paper ground into a circle. Nothing
   here should set a size on it. */
.footer-brand p { font-size: 13px; font-weight: 700; }
.footer-brand span { display: block; font-weight: normal; font-size: 11px; color: #b7cbd0; margin-top: 3px; }
.footer-inner > a { font-size: 13px; padding-block: 12px; }
.legal { display: flex; gap: 18px; font-size: 11px; color: #c9d7da; }
.legal a { padding-block: 15px; }

/* --- public components shared by more than one page --- */
.page-heading { padding: 24px 0 16px; display: flex; justify-content: space-between; align-items: end; gap: 36px; }
.eyebrow, .label { display: block; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.eyebrow { color: var(--red); margin-bottom: 12px; }
.heading-note { font-size: 14px; color: var(--muted); max-width: 270px; flex-shrink: 0; line-height: 1.65; }
.heading-note a { text-decoration: underline; text-underline-offset: 4px; }
.button {
  display: inline-flex;
  justify-content: space-between;
  align-items: center;
  gap: 30px;
  min-height: 48px;
  padding: 12px 20px;
  background: var(--red);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
}
.order-bar { display: flex; justify-content: space-between; align-items: center; gap: 20px; border-bottom: 1px solid var(--line); padding: 20px 0; }
.order-bar p { font-size: 14px; color: var(--muted); }
.text-link {
  display: inline-flex;
  align-items: center;
  gap: 28px;
  min-height: 44px;
  font-size: 14px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 5px;
}
.quiet-link {
  display: block;
  width: fit-content;
  color: var(--muted);
  font-size: 13px;
  padding-block: 13px;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.feed-state { padding: 20px 0; color: var(--muted); font-size: 14px; }
.feed-state button, .feed-state + button { margin-top: 12px; padding: 10px 18px; min-height: 44px; background: var(--navy); color: #fff; border: 0; cursor: pointer; }
.feed-state + button { margin-top: 0; margin-bottom: 20px; }


/* ==========================================================================
   4. Public pages
   ========================================================================== */

/* --- This week (/) --- */
.landing-strip { display: flex; gap: 48px; padding: 18px 24px; background: var(--ice); border-left: 3px solid var(--navy); }
.landing-strip > div { display: flex; align-items: baseline; gap: 14px; }
.landing-strip .label { color: var(--muted); font-size: 10px; }
.landing-strip strong { font-size: 16px; }

.section-heading { display: flex; align-items: center; justify-content: space-between; padding: 14px 0 10px; gap: 16px; }
.section-heading h2 { font-size: 23px; }
.section-heading a { font-size: 13px; text-decoration: underline; text-underline-offset: 4px; padding-block: 10px; }

.list-head {
  display: grid;
  grid-template-columns: 1.05fr 1.25fr .65fr;
  gap: 20px;
  padding: 12px 22px;
  background: var(--navy);
  color: #d8e4e7;
  font-size: 10px;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: .12em;
}
.list-head span:last-child { text-align: right; }

.product-list { list-style: none; margin: 0; padding: 0; background: var(--white); border-inline: 1px solid var(--line); }
.product-row {
  display: grid;
  grid-template-columns: 1.05fr 1.25fr .65fr;
  gap: 20px;
  align-items: center;
  padding: 23px 22px;
  border-bottom: 1px solid var(--line);
}
.product-name { font-size: 20px; font-weight: 700; letter-spacing: -.025em; line-height: 1.22; }
.product-details { font-size: 13px; line-height: 1.5; color: var(--muted); }
.product-details span { display: block; }
.status-wrap { text-align: right; }

/* status pill: base grey = closed / not this week; .open green; .sold red */
.status {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  font-weight: bold;
  line-height: 1.3;
  padding: 6px 8px;
  background: var(--ice);
  color: var(--muted);
  max-width: 100%;
}
.status:before { content: ""; width: 5px; height: 5px; flex: 0 0 5px; background: currentColor; }
.status.open { color: var(--green); background: #e8f0e8; }
/* On a product listing, "available" is the answer the buyer came for, so it is
   the one pill that carries weight: white on --green is 7.56:1, and .status:before
   takes currentColor so the dot follows. Scoped away from /orders/, where these
   same class names mean order states and must stay quiet. */
.row .status.open, .catalog-item .status.open { background: var(--green); color: #fff; }
/* On a product listing, "available" is the answer the buyer came for, so it is
   the one pill that carries weight: white on --green is 7.56:1, and .status:before
   takes currentColor so the dot follows. Scoped away from /orders/, where these
   same class names mean order states and must stay quiet. */
.row .status.open, .catalog-item .status.open, .feature .status.open { background: var(--green); color: #fff; }
.status.sold { color: #a13324; background: #faebe4; }
.status.closed { color: var(--muted); background: var(--ice); }
/* A cap is a warning, not an alarm: amber sits between the green of Available
   and the red of Sold out. The number behind it is never shown to a customer. */
/* Coming soon: not running yet, but expected. Navy rather than the amber
   Limited already owns -- two amber chips a row apart would read as the same
   state. This one is an invitation to ask, not a warning about supply. */
.status.soon { color: var(--navy); background: #e7eef3; }
.status.limited { color: #8a5520; background: #f7efe2; }
.status-note { display: block; color: var(--muted); font-size: 11px; margin-top: 5px; }
.product-row.inactive .product-name { color: #53636a; }

.week-bottom { display: grid; grid-template-columns: 1.15fr 1fr; gap: 48px; margin-top: 48px; align-items: center; }
.product-photo { position: relative; }
.product-photo img { width: 100%; height: 244px; object-fit: cover; }
.product-photo figcaption { position: absolute; bottom: 0; left: 0; background: var(--navy); color: #fff; font-size: 11px; padding: 9px 14px; }
.new-account h2 { font-size: 32px; max-width: 310px; }
.new-account > p:not(.eyebrow) { color: var(--muted); font-size: 14px; margin: 14px 0 18px; }

/* --- Products (/products/) --- */
.search-wrap { max-width: 520px; margin-top: 8px; }
.search-wrap label { display: block; font-size: 13px; font-weight: bold; margin-bottom: 8px; }
.search-wrap input {
  width: 100%;
  padding: 14px;
  border: 1px solid #82979e;
  background: var(--white);
  color: var(--ink);
  border-radius: 0;
  font-size: 16px;
}
.result-count { font-size: 12px; color: var(--muted); margin: 18px 0; }

/* --- Contact (/contact/) --- */
.contact-layout { display: grid; grid-template-columns: 1.2fr 1fr; gap: 50px; margin-top: 10px; }
.contact-primary .label { color: var(--muted); }
.phone { display: block; font-weight: 700; font-size: clamp(27px, 3vw, 40px); letter-spacing: -.03em; padding-block: 10px; }
/* The underline runs straight under the parentheses. Left to skip them, it
   broke around the descending "(" and left a sliver at the far left that read
   as a stray full stop under the number (Brian, 24 Sep). */
.phone { text-decoration-skip-ink: none; }
.contact-primary > p { font-size: 14px; color: var(--muted); }
.contact-primary .service-area { margin-top: 32px; line-height: 1.9; }
.contact-account { background: var(--ice); padding: 30px; }
.contact-account > p { margin: 14px 0 22px; font-size: 14px; color: var(--muted); }
/* the short company block under the contact layout */
.company-facts { margin-top: 48px; border-top: 1px solid var(--line); padding-top: 30px; }
.company-facts h2 { font-size: 23px; }
/* Three facts, one row, stacked label over value: at a third of the width a
   120px label column would leave the value on two or three ragged lines. */
.facts-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 30px; margin: 10px 0 0; }
.facts-list div { padding: 10px 0 12px; border-top: 1px solid var(--line); border-bottom: 0; font-size: 14px; line-height: 1.5; }
.facts-list dt { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-bottom: 5px; }
.facts-list dd { margin: 0; }


/* ==========================================================================
   5. App components (buyer, legal, desk pages)
   Everything here is scoped so it never reaches the public pages: app pages
   put their content in div.wrap; public pages use main.shell.
   ========================================================================== */

/* --- layout --- */
.wrap { max-width: 1464px; margin: 0 auto; padding: 0 32px; }
:where(.wrap) section { padding: var(--s6) 0; }
:where(.wrap) section.head { padding-bottom: var(--s5); }
:where(.wrap) section.head + section { padding-top: 0; }
.head h1 { margin-bottom: var(--s4); }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s6); }
.desk { max-width: none; }
.cta { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin: 0; }
.rule { border: 0; border-top: 1px solid var(--rule); margin: 0; }

/* --- type --- */
:where(.wrap) p { margin: 0 0 var(--s4); }
:where(.wrap) h2 { margin-bottom: var(--s4); }
:where(.wrap) :is(p, td, dd) a { border-bottom: 1px solid var(--rule); }
:where(.wrap) :is(p, td, dd) a:hover { border-bottom-color: var(--ink); }
.kicker { display: block; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--red); margin-bottom: var(--s3); }
.lbl { display: block; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-bottom: var(--s2); }
.lede { font-size: 17px; line-height: 1.55; max-width: 58ch; color: var(--muted); }
.help { font-size: 13px; color: var(--muted); margin-top: var(--s2); }
.msg { border-left: 3px solid var(--red); padding-left: var(--s4); margin: var(--s4) 0; }
.small { font-size: 13.5px; line-height: 1.55; }
.mono { font-family: var(--mono); }
.dim { color: var(--muted); }
.strong { font-weight: 700; }
.board-note { font-size: 14px; color: var(--muted); margin-top: var(--s4); }
.fishart { width: auto; height: 250px; display: block; }

/* --- panels and cards --- */
.panel { background: var(--card); border: 1px solid var(--rule); padding: var(--s5); }
.panel h2, .panel h3 { margin-bottom: var(--s3); }
.panel p:last-child { margin-bottom: 0; }
.card { border: 1px solid var(--rule); background: var(--card); padding: var(--s4); margin-bottom: var(--s4); }
.card h3 { margin-bottom: var(--s2); }
.card .meta { font-size: 12.5px; color: var(--muted); margin-bottom: var(--s3); }
.card .sub { font-size: 12.5px; color: var(--muted); }
.card input[type=text] { width: 120px; padding: 6px var(--s2); }
.card input[type=number] { width: 92px; text-align: right; padding: 6px var(--s2); }
.card table { margin-bottom: var(--s3); }
.card .st {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 3px 7px;
  border: 1px solid var(--rule);
  margin-left: var(--s2);
  vertical-align: middle;
}
.card .st.new { background: var(--red); color: #fff; border-color: var(--red); }
.card .st.accepted { background: var(--navy); color: #fff; border-color: var(--navy); }

/* --- forms --- */
form { max-width: 640px; }
.field { margin-bottom: var(--s4); }
label { display: block; font-size: 13px; font-weight: 700; margin-bottom: var(--s2); }
input, select, textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--white);
  border: 1px solid #82979e;
  padding: 11px var(--s3);
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
}
select {
  background: var(--white) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' fill='none' stroke='%23172d37' stroke-width='1.6'/%3E%3C/svg%3E") no-repeat right var(--s3) center;
  background-size: 11px 7px;
  padding-right: 34px;
}
textarea { min-height: 104px; resize: vertical; }
input[type=checkbox], input[type=radio] { width: auto; -webkit-appearance: auto; appearance: auto; }
.hp { position: absolute; left: -9999px; }   /* honeypot wrapper on /trade/ */

/* --- buttons --- */
button {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.2;
  background: var(--navy);
  color: #fff;
  border: 1px solid var(--navy);
  padding: 12px var(--s5);
  cursor: pointer;
  border-radius: 0;
}
button:hover { background: var(--navy-deep); border-color: var(--navy-deep); }
button:disabled { opacity: .6; cursor: default; }
.btn {
  display: inline-block;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.15;
  background: var(--navy);
  color: #fff;
  border: 1px solid var(--navy);
  padding: 11px var(--s4);
}
.btn:hover { background: var(--navy-deep); border-color: var(--navy-deep); }
.btn-sm { font-size: 12.5px; padding: 8px 13px; }

/* --- tables --- */
table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
th, td { text-align: left; padding: var(--s3) var(--s4) var(--s3) 0; border-bottom: 1px solid var(--rule2); vertical-align: top; }
thead th { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--ink); }
tbody th { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); width: 30%; white-space: nowrap; }
td.nw { white-space: nowrap; }

/* --- tabs (desk) --- */
.tabs { display: flex; gap: var(--s4); margin-bottom: var(--s5); border-bottom: 1px solid var(--rule); }
.tabs button {
  background: none;
  border: 0;
  border-bottom: 3px solid transparent;
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
  padding: 0 0 var(--s2);
  cursor: pointer;
}
.tabs button:hover { background: none; color: var(--navy); border-color: transparent; }
.tabs button.on, .tabs button.on:hover { border-bottom-color: var(--red); }

/* --- the week and its rows (/live-list/) --- */
.week {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--ink);
  padding-bottom: var(--s3);
  margin-bottom: var(--s4);
}
.week .lands { font-size: 22px; font-weight: 700; letter-spacing: -.02em; }
/* --- The Live List: an order grid ----------------------------------------
   Six labelled columns, because a buyer has to be able to check the arithmetic
   without doing it in their head. Product, Case (how much one case is), Price
   (the unit price and the case price), Cases (always a count of cases, never a
   weight), Ordered (the weight that count comes to — what the packing list is
   counted in) and Amount (the line total, the only column that means money).
   The multiplication is on the page before anything is typed, and the line
   total appears the moment it is. */
.lhead, .lrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 70px 124px 92px 84px 112px;
  gap: var(--s4); align-items: center;
}
/* The board is the one thing on this site a buyer works in rather than reads, so
   it is an object with edges: a panel on white, the navy header as its lid. On
   the paper ground it used to be loose rows with nothing holding them. */
#weekbody, #standing-rows {
  background: var(--white);
  border: 1px solid var(--edge);
  border-radius: 2px;
  overflow: hidden;
}
/* Filled navy: 10.01:1, and the only dark mass inside the content field on the
   page a buyer spends their money on. Everything else here is a tint.
   --s4 of side padding, matched by every row under it, so the columns line up
   and nothing sits against the edge. */
.lhead {
  padding: 10px var(--s4); border-bottom: 0;
  background: var(--navy); color: #e6edef;
  font-size: 10px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
}
.lhead > :not(:first-child) { text-align: right; }
.lrow { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--edge); }
.lrow:last-child { border-bottom: 0; }

/* A product name and its amount are some 700px apart on a wide screen, and that
   gap is exactly where the eye loses the row. Three things carry it across:
   a hairline down each gutter, a faint stripe on alternate rows, and a wash on
   the row under the pointer. */
.lhead > :not(:first-child),
.lrow > div:not(:first-child) {
  border-left: 1px solid var(--edge);
  padding-left: var(--s3);
}
/* Nothing to divide from at the panel edge. */
.lrow > div:last-child, .lhead > :last-child { padding-right: 0; }
/* On the navy header band the gutter has to read against navy, not against paper. */
.lhead > :not(:first-child) { border-left-color: #3d5b66; }
/* The alternating stripe was 1.05:1 — two weak devices read worse than one real
   one, so with hairlines that exist the stripe is noise. The hover wash is the
   one place the brand rust does real work, so it is strengthened rather than
   dropped. */
.lrow:hover { background: #d2765c33; }
.lrow .nm { font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.lrow .sub { display: block; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.lcase, .lrow .pr, .lqty, .ltot, .lamt { text-align: right; font-variant-numeric: tabular-nums; }
/* The weight actually being ordered. It is the number the kitchen counts in and
   the number on the packing list, so it gets a column rather than a footnote. */
.ltot { font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--ink); }
.lrow.out .ltot, .ltot.none { font-weight: 400; color: var(--muted); }
.lcase { font-family: var(--mono); font-size: 13px; color: var(--muted); }
.lrow .pr { font-family: var(--mono); font-size: 15px; }
.lrow .pr small { display: block; font-size: 11px; color: var(--muted); }
.lrow .pr .percase { color: var(--ink); font-weight: 700; }
.lrow input { width: 92px; text-align: right; }
/* A locked order's quantities are still worth reading, so they stay on the page
   rather than disappearing — but they must not look like something you can type
   into. readOnly alone is invisible: the box looked exactly as editable as it
   does when it is. */
.lrow input[readonly] {
  background: var(--ice); color: var(--muted);
  border-color: #cfd6d3; cursor: not-allowed;
}
.lrow input[readonly] + .unit { color: var(--muted); }
.lqty .unit { display: block; font-size: 11px; color: var(--muted); margin-top: 3px; }
.lamt { font-family: var(--mono); font-size: 16px; font-weight: 700; }
/* opacity faded the one line that says WHY a row is unavailable — sold out, or
   closed at 4pm — to 2.05:1. The row still has to recede; the reason still has to
   be readable. A filled surface does both: --ink on --ice is 10.37:1. */
.lrow.out { background: var(--ice); }
.lrow.out .nm { color: var(--muted); }
.lrow.out:hover { background: var(--ice); }

/* The weekly order on /account/ borrows the Live List's row, without the price
   and amount columns: what it repeats is a quantity, not a charge. */
#standing .lhead, #standing .lrow { grid-template-columns: minmax(0, 1fr) 84px 104px 120px; }
#standing .order-line p > span { display: block; font-size: 12px; color: var(--red); margin-top: 3px; }
#standing .part-case { color: #8a5520; }
@media (max-width: 760px) {
  #standing .lhead { display: none; }
  #standing .lrow { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "nm nm" "cs qt" "tot tot"; }
  #standing .lrow > div:nth-child(1) { grid-area: nm; }
  #standing .lrow > div:nth-child(2) { grid-area: cs; text-align: left; }
  #standing .lrow > div:nth-child(3) { grid-area: qt; }
  #standing .lrow > div:nth-child(4) { grid-area: tot; text-align: left; }
}

/* While a confirmation is open it owns the decision. The page's own Place order
   and Skip buttons sit after #review, so two "Place order" buttons were on
   screen at once and it was not obvious which one committed the order. Done in
   the cascade rather than in script so it also covers the skip confirmation and
   the cancel-the-edit confirmation. */
#review:not([hidden]) ~ button,
#review:not([hidden]) ~ .help { display: none; }
.lrow.out input { display: none; }
.runtot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-top: 2px solid var(--ink);
  padding-top: var(--s3);
  margin-top: var(--s3);
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Show / hide on a password field. The button sits inside the field's box rather
   than beside it, so the row does not grow and the layout does not move when the
   label changes between Show and Hide. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; padding-right: 74px; }
.pw-peek {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  min-height: 34px; padding: 6px 10px; border: 0; background: none;
  font: 600 12px var(--sans); color: var(--navy); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}
.pw-peek:hover { color: var(--red); }
/* Edge and IE draw their own reveal control; two would be silly. */
.pw-wrap input::-ms-reveal, .pw-wrap input::-ms-clear { display: none; }

.lockbar { border-left: 3px solid var(--navy); background: var(--ice); padding: var(--s3) var(--s4); margin-bottom: var(--s5); }
/* One bar carried every state — order in and changeable, order packed and final,
   week shut — in the same navy on the same ice. Those three have entirely
   different consequences for a buyer and read identically at a glance, which is
   how somebody ends up staring at a greyed board wondering which it is.
   Colour AND a leading label, so the distinction survives greyscale, a bright
   kitchen and colour-blindness. */
.lockbar.is-placed { border-left-color: var(--green); }
.lockbar.is-placed .lbl { color: var(--green); }
.lockbar.is-shut { border-left-color: var(--red); background: #f6e9e3; }
.lockbar.is-shut .lbl { color: var(--red); }
.lockbar.is-done { border-left-color: var(--muted); }
.signin-panel { max-width: 420px; }   /* the sign-in panel (was .signin; .signin is now the header button) */

/* --- review step (nav.js gwsAsk and the live-list review) --- */
.review { border: 1px solid var(--line); border-left: 3px solid var(--navy); background: var(--ice); padding: var(--s4); margin: var(--s4) 0; }
.review .lbl { margin-bottom: var(--s3); }
.review ul { list-style: none; margin: 0 0 var(--s3); padding: 0; font-size: 14px; }
.review li { display: flex; justify-content: space-between; gap: var(--s4); padding: 5px 0; border-bottom: 1px solid var(--line); }
.review li:last-child { border-bottom: 0; }
.review li .q { font-family: var(--mono); white-space: nowrap; }
.review .tot { display: flex; justify-content: space-between; border-top: 2px solid var(--ink); padding-top: var(--s2); font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.review .warn { color: var(--red); }
.review .acts { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4); }
.review .acts .ghost { background: none; color: var(--ink); border-color: var(--ink); }
.review .acts .ghost:hover { background: none; color: var(--red); border-color: var(--red); }

/* --- desk odds and ends --- */
.step.off { opacity: .45; }
.step.off input, .step.off button, .step.off textarea { pointer-events: none; }
.gate { font-size: 12.5px; font-weight: 700; color: var(--red); border-left: 2px solid var(--red); padding-left: var(--s3); margin: var(--s3) 0; }
.trail { border-top: 1px solid var(--rule2); padding: var(--s3) 0; display: grid; grid-template-columns: 150px 1fr; gap: var(--s4); }
.trail .when { font-family: var(--mono); font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.trail .what { font-size: 14px; }
.trail .who { font-size: 12px; color: var(--muted); }
.qty { display: flex; align-items: baseline; gap: var(--s2); }
.qty input { width: 78px; text-align: right; }
.qty .u { font-family: var(--mono); font-size: 12px; color: var(--muted); }
#wkrows .cz { width: 190px; }
#wkrows td:first-child { min-width: 186px; }

/* --- order rows (/orders/) --- */
/* --- My orders: the same five columns the Live List uses ------------------
   An order should read the same way whether you are placing it or looking one
   up later. The whole row is the link — the arrow is there because nothing in
   the old row looked as though it could be opened. */
.ohead, .orow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 104px 64px 116px 116px 22px;
  gap: var(--s4); align-items: center;
}
.ohead {
  padding: 0 0 6px; border-bottom: 2px solid var(--ink);
  font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.ohead > :not(:first-child) { text-align: right; }
.orow { padding: var(--s3) 0; border-bottom: 1px solid var(--rule2); }
.orow:last-child { border-bottom: 0; }
.orow-link { color: inherit; }
.orow:nth-child(even) { background: #00000005; }
.orow-link:hover { background: #d2765c14; }
.orow-link:hover .sp, .orow-link:hover .ogo { color: var(--red); }
.orow .sp { font-size: 17px; font-weight: 700; letter-spacing: -.01em; }
.orow .la { display: block; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.oref, .oitems, .ostatus, .orow .pr { text-align: right; font-variant-numeric: tabular-nums; }
.oref { font-family: var(--mono); font-size: 13px; color: var(--muted); }
.oitems { font-size: 14px; color: var(--ink); }
.orow .status { font-size: 10px; padding: 4px 7px; gap: 5px; }
.orow .pr { font-family: var(--mono); font-size: 16px; font-weight: 700; }
.ogo { text-align: right; color: var(--muted); font-size: 15px; }

/* the columns fold on a phone, and each cell names itself once the header is gone */
@media (max-width: 760px) {
  .ohead { display: none; }
  .orow {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "sp sp" "ref status" "items total" "go go";
    gap: var(--s2) var(--s4);
    padding: 13px 14px 14px; margin-bottom: 10px;
    background: var(--white); border: 1px solid var(--line);
  }
  .orow:nth-child(even), .orow-link:hover { background: var(--white); }
  .orow > div:nth-child(1) { grid-area: sp; }
  .orow > div:nth-child(2) { grid-area: ref; text-align: left; }
  .orow > div:nth-child(3) { grid-area: items; text-align: left; }
  .orow > div:nth-child(4) { grid-area: status; }
  .orow > div:nth-child(5) { grid-area: total; }
  .orow > div:nth-child(6) { display: none; }
  .oitems::before { content: "Items"; font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-right: 6px; }
}

/* --- printable documents (/orders/ confirmation, desk purchase order) --- */
.doc { background: var(--card); border: 1px solid var(--rule); padding: var(--s6); margin: var(--s5) 0 var(--s7); max-width: 900px; }
/* Letterhead: the logo and the address on the left, the document's name on the
   right, a rule under both. The name of the business is not set in type here --
   it is in the logo. */
/* The letterhead is a BAND, not a logo floating on white.
   The blue main logo is not a transparent file -- it carries its approved
   painted paper ground, sampled at #F3ECE0 -- and the package forbids knocking
   it out with a filter or a recolor. On the document's near-white #FFFEFA that
   ground reads as a rectangle around the mark. So the head takes the same
   ground and the rectangle becomes the band it was always pretending to be.

   print-color-adjust is the important half: a CSS background normally drops out
   when the page is printed, while the image's own ground is pixels and always
   prints. Without this the box would come back on paper, which is the one place
   these documents actually live. */
.dochead { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s5); border-bottom: 1px solid var(--ink); background: #F3ECE0; padding: var(--s4); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.docmark { display: flex; flex-direction: column; }
.doclogo { width: 240px; max-width: 100%; height: auto; display: block; margin-bottom: 10px; }
.dochead .doctitle { margin: 0; text-align: right; }
/* The seal closes the document, once, at the end -- not repeated per printed
   page, which needs a fixed print footer that behaves differently in every
   browser. 110 is smaller than the 168 the head used to give it, and it can be:
   nobody reads a closing mark, they see it. */
.docfoot { margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--line); text-align: center; }
.docfootseal { width: 110px; height: 110px; display: block; margin: 0 auto 10px; object-fit: contain; border-radius: 50%; }

.docfrom p, .docmark p { margin: 0 0 2px; }
.doctitle { font-size: 30px; margin: var(--s5) 0 var(--s4); }
.docmeta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s4);
  border-top: 1px solid var(--rule2);
  border-bottom: 1px solid var(--rule2);
  padding: var(--s3) 0;
  margin-bottom: var(--s5);
}
.docmeta .k { display: block; font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.docmeta .v { display: block; font-size: 14px; font-weight: 700; margin-top: 4px; line-height: 1.25; }
.docto { margin-bottom: var(--s5); }
.docto p { margin: 0 0 2px; }
.doclines { margin-bottom: var(--s4); }
.doclines thead th { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--ink); padding-bottom: var(--s2); }
.doclines td { vertical-align: top; padding: var(--s3) var(--s3) var(--s3) 0; }
.doclines .num { text-align: right; font-family: var(--mono); font-size: 13.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.doclines .sub { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; }
.doclines .adj { color: var(--red); }
.doctotal {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-top: 2px solid var(--ink);
  padding-top: var(--s3);
  font-size: 21px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.docnote { margin-top: var(--s4); }
.docnote .lbl { display: block; }


/* ==========================================================================
   Buyer pages
   Classes that replaced the inline styles on /live-list/, /orders/, /trade/,
   /terms/, /privacy/ and 404. Scoped like section 5: nothing here reaches the
   public pages. The one media rule stays with its component on purpose.
   ========================================================================== */
:where(.wrap) section.tight { padding-top: 0; }   /* the sign-in section under the heading */
.section-gap { margin-top: var(--s6); }            /* a heading or link row after a list */

/* /live-list/: order notes, preset note, the two order buttons, the desk hand-off */
.notes-field { margin-top: var(--s5); }
.notes-field textarea { min-height: 64px; }
.preset-note { margin-bottom: var(--s4); }
button.quiet { background: none; color: var(--ink); border-color: var(--ink); margin-left: var(--s3); }
button.quiet:hover { background: none; color: var(--red); border-color: var(--red); }
@media (max-width: 620px) {
  button.quiet { display: block; margin: var(--s3) 0 0; }   /* stacks under Place order */
}
.desk-panel { max-width: 520px; }
.desk-panel .cta { margin-top: var(--s4); }

/* sign-in panel: message and links under the button, the two secondary forms */
.form-msg { margin-bottom: 0; }
.form-links { margin-top: var(--s4); }
.subform { margin-top: var(--s4); border-top: 1px solid var(--rule); padding-top: var(--s4); }

/* /orders/: the Print / My orders / Live List row above the document */
.doc-actions { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; padding-top: var(--s5); }

/* /trade/: heading column and the validation message */
.trade-intro h1 { margin-bottom: var(--s4); }
.trade-intro .lede { margin-bottom: var(--s5); }
.form-error { color: var(--red); }

/* /terms/, /privacy/ */
.terms-table th { white-space: normal; }
.review-note { margin-top: var(--s5); }
.prose { max-width: 70ch; }

/* 404 */
.notfound { text-align: center; }
/* The circle at 240, clipped round: the blue artwork is painted on paper and
   square in the file, so without the radius it shows its corners. 240 fits the
   354px a 390px phone leaves inside the gutter. */
.notfound .fishart { width: 240px; height: 240px; margin: 0 auto; border-radius: 50%; object-fit: contain; }
.notfound h1 { margin-top: var(--s5); }
.notfound .lede { margin: 0 auto var(--s4); }


/* ==========================================================================
   6. Responsive
   ========================================================================== */

@media (max-width: 900px) {
  /* app */
  .grid2 { grid-template-columns: 1fr; gap: var(--s5); }
  :where(.wrap) section { padding: var(--s5) 0; }
  .fishart { height: 200px; }
}

@media (max-width: 760px) {
  /* shell */
  .shell { width: calc(100% - 36px); }
  .topbar { display: contents; }
  .nav-band { position: sticky; top: 0; z-index: 5; }
  .masthead-inner { min-height: 82px; gap: 16px; flex-wrap: wrap; }
  .masthead-note { font-size: 12px; }
  .masthead-note span { display: none; }
  .headright { margin-left: auto; gap: 14px; }
  .account-nav { gap: 12px; }
  .account-nav a, .headright .headtel { font-size: 12px; }
  .masthead .signin { font-size: 13px; min-height: 44px; padding: 11px 14px; gap: 15px; }
  .navigation { width: 100%; }
  .navigation a { min-height: 52px; font-size: 13px; }
  .page-heading { padding: 28px 0 23px; display: block; }
  .page-heading h1 { font-size: 34px; max-width: 400px; }
  .eyebrow { font-size: 10px; margin-bottom: 10px; }
  .heading-note { margin-top: 12px; font-size: 13px; max-width: none; }
  .heading-note br { display: none; }
  .order-bar { padding: 16px 0; gap: 10px; }
  .order-bar p { font-size: 12px; }
  .button { font-size: 13px; gap: 18px; padding: 12px 16px; }
  .footer-inner { flex-wrap: wrap; gap: 10px 25px; padding-block: 24px; }
  .footer-brand { width: 100%; margin: 0 0 8px; }
  .legal { margin-left: auto; }
  main { padding-bottom: 36px; }

  /* This week */
  .landing-strip { padding: 14px 15px; gap: 8px; display: grid; }
  .landing-strip > div { display: grid; grid-template-columns: 64px 1fr; gap: 10px; }
  .landing-strip strong { font-size: 14px; }
  .section-heading { padding: 19px 0 10px; }
  .section-heading h2 { font-size: 21px; }
  .list-head { display: none; }
  .product-list { border: 1px solid var(--line); border-bottom: 0; }
  .product-row { grid-template-columns: minmax(0, 1fr) auto; gap: 6px 10px; padding: 18px 16px; align-items: start; }
  .product-name { font-size: 20px; grid-column: 1; grid-row: 1; }
  .product-details { grid-column: 1 / -1; grid-row: 2; font-size: 12px; max-width: 95%; line-height: 1.55; }
  .product-details span { display: inline; }
  .product-details span + span:before { content: " · "; }
  .status-wrap { grid-column: 2; grid-row: 1; max-width: 116px; }
  .status { font-size: 10px; padding: 5px 6px; gap: 5px; }
  .status-note { font-size: 10px; }
  .week-bottom { grid-template-columns: 1fr; gap: 25px; margin-top: 30px; }
  .product-photo img { height: 190px; }
  .new-account h2 { font-size: 28px; max-width: none; }
  .new-account > p:not(.eyebrow) { margin: 10px 0; }
  .new-account { padding: 0 0 4px; }

  /* Products: see the Products section for the full column ladder */

  /* Contact */
  .contact-layout { grid-template-columns: 1fr; gap: 30px; }
  .contact-account { padding: 23px; }
  .company-facts { margin-top: 34px; padding-top: 24px; }
  .facts-list { grid-template-columns: 1fr; }

  /* app */
  .wrap { padding: 0 18px; }
  table.resp, table.resp tbody, table.resp tr, table.resp td { display: block; width: auto; }
  table.resp thead { display: none; }
  table.resp tr { border-bottom: 1px solid var(--rule); padding: var(--s3) 0; }
  table.resp tr:last-child { border-bottom: 0; }
  table.resp td { border: 0; padding: 4px 0; display: flex; justify-content: space-between; align-items: baseline; gap: var(--s4); text-align: right; }
  table.resp td::before {
    content: attr(data-l);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--muted);
    text-align: left;
    flex: 0 0 auto;
  }
  table.resp td:empty { display: none; }
  .card input[type=text], .card input[type=number] { width: 120px; }
  .desk .tabs { gap: var(--s4); overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .desk .tabs button { white-space: nowrap; }
}

@media (max-width: 900px) {
  /* app: live-list rows stack name / price / quantity */
  /* the header cannot survive at this width; every cell labels itself instead */
  .lhead { display: none; }
  .lrow {
    grid-template-columns: 1fr auto;
    grid-template-areas: "nm nm" "cs qt" "pr tot" "amt amt";
    gap: var(--s2) var(--s4); align-items: center;
    padding: 13px 14px 14px;
    background: var(--white); border: 1px solid var(--line);
    margin-bottom: 10px;
  }
  /* the card is the separator, so the striping and the last-row exception both go */
  .lrow:nth-child(odd), .lrow:hover { background: var(--white); }
  .lrow:last-child { border-bottom: 1px solid var(--line); margin-bottom: 0; }
  .lrow.out { background: #00000004; }
  .lrow > div:nth-child(1) { grid-area: nm; }
  .lrow > div:nth-child(2) { grid-area: cs; text-align: left; }
  .lrow > div:nth-child(3) { grid-area: pr; text-align: left; display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap; }
  .lrow > div:nth-child(4) { grid-area: qt; }
  .lrow > div:nth-child(5) { grid-area: tot; }
  .lrow > div:nth-child(6) { grid-area: amt; border-top: 1px solid var(--rule2); margin-top: 2px; padding-top: var(--s3); display: flex; justify-content: space-between; align-items: baseline; }
  /* The column header is gone at this width, so each number names itself —
     without this, the case size and the ordered total both read "10 lb". */
  .lcase::before, .ltot::before, .lamt::before {
    font-family: var(--sans); font-size: 10px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted); margin-right: 6px;
  }
  .lcase::before { content: "Case"; }
  /* The weight, not the money — the same word the printed order uses. */
  .ltot::before  { content: "Ordered"; }
  .lamt::before  { content: "Amount"; }
  .lrow .pr small { display: inline; }
  .lrow input { width: 110px; }
  .lrow > div:not(:first-child) { border-left: 0; padding-left: 0; }

}

/* Lifted out of the order-grid block, which now folds at 900px: the activity
   trail was always a 620px change and has nothing to do with those columns. */
@media (max-width: 620px) {
  .trail { grid-template-columns: 1fr; gap: var(--s1); }
}

@media (max-width: 350px) {
  /* shell */
  .shell { width: calc(100% - 28px); }
  .navigation { width: 100%; }
  .masthead .signin { padding-inline: 11px; }
  .navigation a { font-size: 12px; }
  .page-heading h1 { font-size: 30px; }
  .order-bar p { max-width: 72px; }
  .footer-inner { gap: 8px 16px; }
  /* This week */
  .product-row { padding-inline: 12px; }
  .product-name { font-size: 18px; }
  /* app */
  .wrap { padding: 0 14px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}


/* ==========================================================================
   7. Print (order confirmations and desk documents)
   ========================================================================== */
@media print {
  header.site, footer.site, .nav-band, .skip, .noprint, #listwrap { display: none !important; }
  body { background: #fff; color: #000; font-size: 10.5pt; display: block; }
  main { flex: none; min-height: 0; padding-bottom: 0; }
  .wrap { max-width: none; padding: 0; }
  section { padding: 0; }
  .doc { border: 0; background: #fff; padding: 0; margin: 0; max-width: none; }
  .doclines td, .doclines th { padding-top: 6pt; padding-bottom: 6pt; }
  .doclines .adj { color: #000; font-weight: 700; }
  a { border-bottom: 0 !important; color: #000; }
  .doclines, .doctotal, .dochead { page-break-inside: avoid; }
}

/* The Live List quantity box counts cases, not pounds, wherever a product has a
   case size. This caption sits under the box and says what one case is, so the
   number in the box is never ambiguous. */

/* ===========================================================================
   THIS WEEK, PRODUCTS AND THE LIVE LIST — 7 September 2026

   One block, authored once. This replaced four blocks of overrides appended on
   top of each other over the course of a day, where .catalog-item was redefined
   eighteen times, .brand thirteen, and .week-shell twice with two different
   widths. The page rendered correctly only because of cascade order, which is
   not a design.

   The governing rule here is that the page has ONE grid. .navigation is three
   equal columns, so the split below it is the same three columns: the picture
   takes column one, the board takes two and three. The left column therefore
   ends exactly where "This week" ends and the board begins exactly where
   "Products" begins. There is no page-specific shell width — a second container
   width was what put the content 110px outside the menu on both sides.
   =========================================================================== */

/* --- This week: the approved composition (Design Study 03) ---------------
   Two columns at 37/63 with a 25px gap and 26px side padding, the feature under
   a rust top edge, and a 2px navy rule above "The weekly list" inset to the row
   content. Live / Fresh / Frozen are distinct compact headings, and product
   condition is kept separate from weekly availability: the group says how it is
   stored, the pill on the right says whether you can have it this week. */

.week-page { padding-inline: 26px; }

.week-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 30px; flex-wrap: wrap; padding: 12px 0 11px;
}
.week-head h1 {
  font-family: var(--title); font-size: clamp(26px, 2.2vw, 34px);
  font-weight: 400; line-height: 1.1; letter-spacing: -.025em;
}
/* "Arrives" is the seafood landing, not a promise of delivery to one customer */
.week-arrival { display: flex; gap: 26px; padding-left: 23px; border-left: 2px solid var(--navy); flex-shrink: 0; }
.week-arrival .caption { display: block; font-size: 10px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.week-arrival strong { font-size: 15px; font-weight: 600; }

.week-columns { display: grid; grid-template-columns: minmax(0, .37fr) minmax(0, .63fr); gap: 25px; align-items: start; }

/* the feature */
.feature { background: var(--white); border: 1px solid var(--line); border-top: 3px solid var(--red); overflow: hidden; }
.feature-photo { display: block; width: 100%; padding: 0; border: 0; background: none; line-height: 0; cursor: zoom-in; }
.feature-photo img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.feature-photo:focus-visible { outline: 3px solid #cf762d; outline-offset: -3px; }
.feature-copy { padding: 15px 18px 17px; }
.feature .overline { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.feature h2 { font-family: var(--title); font-size: 22px; font-weight: 400; line-height: 1.2; letter-spacing: -.025em; margin-top: 5px; }
.feature h2 span { color: var(--red); }
.feature-source { font-size: 13px; color: var(--muted); margin-top: 7px; }
.feature-facts { display: flex; align-items: center; gap: 11px; margin-top: 9px; font-size: 13px; }
.live-word { color: var(--green); font-size: 11px; letter-spacing: .09em; font-weight: 700; border-right: 1px solid var(--line); padding-right: 11px; }
.feature-bottom { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-top: 13px; border-top: 1px solid var(--line); padding-top: 6px; }
.feature-bottom .text-action { font-size: 12px; text-decoration: underline; text-underline-offset: 3px; }

/* the list */
.week-list { min-width: 0; }
.list-title {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  border-top: 2px solid var(--navy); padding: 5px 12px 0; min-height: 27px; margin-bottom: 5px;
}
.list-title h2 { font-size: 16px; font-weight: 600; letter-spacing: -.02em; }
.list-title .link-button { font-size: 12px; text-decoration: underline; text-underline-offset: 3px; color: var(--muted); }

.group { margin-bottom: 4px; }
.group-head {
  display: grid; grid-template-columns: minmax(0, 1fr) 86px 111px; align-items: center;
  gap: 20px; padding: 6px 18px;
  background: var(--group-live); border-top: 2px solid var(--green); color: #264f3e;
}
.group-head h3 { font-family: var(--title); font-size: 19px; font-weight: 400; line-height: 1.2; letter-spacing: -.025em; }
.group-head > span { font-size: 10px; letter-spacing: .08em; font-weight: 500; text-align: right; }
.group[data-kind="fresh"]  > .group-head { background: var(--group-fresh); border-color: #687c7d; color: #3f575a; }
.group[data-kind="frozen"] > .group-head { background: var(--group-frozen); border-color: #56758a; color: #355166; }
.group[data-kind="other"]  > .group-head { background: var(--group-other); border-color: var(--muted); color: var(--ink); }

.row {
  display: grid; grid-template-columns: minmax(0, 1fr) 86px 111px; align-items: center;
  gap: 20px; padding: 5px 18px; background: var(--white); border-bottom: 1px solid var(--edge);
}
.row:last-child { border-bottom: 0; }
.row-name { font-size: 17px; font-weight: 600; line-height: 1.25; letter-spacing: -.02em; }
.row-origin { display: flex; flex-wrap: wrap; gap: 1px 14px; font-size: 12px; margin-top: 2px; color: var(--muted); }
.row-unit { font-size: 13px; text-align: right; color: var(--ink); }
.row .status-wrap { text-align: right; }
/* Not opacity: it fades the pill's own background with the text and takes the
   one word that matters — Sold out, Closed — to 2.36:1. A quieter surface makes
   the row recede and leaves every label at full strength. */
.row.inactive { background: #f2efe8; }
.row.inactive .row-name { color: var(--muted); }
/* the one product the business is built on */
.row-signature { border-left: 2px solid var(--red); }
.row-signature .row-name { color: var(--red); }

.order-line {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  border-top: 1px solid var(--line); padding-top: 10px; margin-top: 4px;
}
.order-line p { font-size: 15px; font-weight: 500; }
.order-line p > span { display: block; font-size: 12px; color: var(--muted); font-weight: 400; margin-top: 3px; }

/* Phones: the columns stack and the feature becomes a compact horizontal
   photo-and-copy treatment above the list. The desktop page is never scaled
   down into a phone canvas. */
@media (max-width: 900px) {
  .week-page { padding-inline: 16px; }
  .week-columns { grid-template-columns: 1fr; gap: 18px; }
  .week-head { padding: 14px 0 12px; }
  .feature { display: grid; grid-template-columns: minmax(0, .42fr) minmax(0, .58fr); }
  .feature-photo img { height: 100%; aspect-ratio: auto; min-height: 128px; }
  .feature-copy { padding: 12px 14px 13px; }
  .feature h2 { font-size: 19px; }
  .group-head, .row { grid-template-columns: minmax(0, 1fr) 64px 92px; gap: 12px; padding-inline: 14px; }
  .row-name { font-size: 15px; }
}
@media (max-width: 520px) {
  /* The feature stays horizontal on a phone. Stacking it puts a 16/9 photo
     across the screen and pushes the list off the first screen, which is the
     opposite of what the approved version does. */
  .feature { grid-template-columns: minmax(0, .38fr) minmax(0, .62fr); }
  .feature-photo img { min-height: 112px; }
  .feature-copy { padding: 10px 12px 11px; }
  .feature h2 { font-size: 17px; }
  .feature-source, .feature-facts { margin-top: 5px; font-size: 12px; }
  .feature-bottom { margin-top: 9px; padding-top: 5px; }
  .week-arrival { padding-left: 14px; gap: 18px; }
  .group-head, .row { grid-template-columns: minmax(0, 1fr) auto; }
  .group-head > span:first-of-type { display: none; }
  .row > .row-main { grid-column: 1; grid-row: 1; }
  .row-unit { grid-column: 1; grid-row: 2; text-align: left; font-size: 12px; color: var(--muted); margin-top: 2px; }
  .row .status-wrap { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
  .row-origin { font-size: 11px; }
}

/* --- Products: a list to scan -------------------------------------------- */

/* Cards on the same white surface as the weekly list, with the top edge
   carrying the product's condition in the same colours the week list gives its
   Live / Fresh / Frozen groups. The photo column is reserved on every card,
   photo or not, so names start on the same line and text blocks are the same
   width — reserved, not filled with a grey plate: most of the line will never
   be photographed and a column of empty rectangles reads as broken. */
.catalog {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px; list-style: none; padding: 0; margin: 0;
}
.catalog-item {
  display: grid; grid-template-columns: minmax(0, 1fr);
  column-gap: 16px; align-content: start;
  background: var(--white); border: 1px solid var(--edge);
  border-top: 2px solid var(--muted);
  padding: 13px 16px 14px;
}
.catalog-item > *:not(.catalog-shot) { grid-column: 1; }
/* the photo column exists only on a card that has a photo: inside a bordered
   card an empty reserved column reads as a mistake, and names still line up
   because every card starts at the same left edge */
.catalog-item:has(.catalog-shot) { grid-template-columns: minmax(0, 1fr) 108px; }
.catalog-item.targeted { outline: 2px solid var(--red); outline-offset: 2px; }
.catalog-item[data-kind="live"]   { border-top-color: var(--green); }
.catalog-item[data-kind="fresh"]  { border-top-color: #687c7d; }
.catalog-item[data-kind="frozen"] { border-top-color: #56758a; }

.catalog-item h2 { font-size: 17px; font-weight: 600; letter-spacing: -.02em; line-height: 1.25; }
.catalog-item p { font-size: 13px; color: var(--muted); margin-top: 4px; }
.catalog-item .catalog-season,
.catalog-item details { margin-top: 6px; }
.catalog-item details { font-size: 12px; color: var(--muted); }
.catalog-item summary { cursor: pointer; min-height: 30px; display: flex; align-items: center; text-decoration: underline; text-underline-offset: 4px; }
.catalog-item .catalog-season { font-size: 12px; }

/* name on the left, availability on the right: one row, never wrapped */
.catalog-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.catalog-head .status-wrap { flex-shrink: 0; }
.catalog-item .status { font-size: 10px; padding: 4px 7px; gap: 5px; }
.catalog-item .status-note { font-size: 10px; }

/* how it is stored — a different fact from whether it is available this week */
.catalog-meta { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.kind-tag {
  font-size: 10px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase;
  padding: 2px 6px; background: var(--ice); color: var(--ink);
}
.catalog-item[data-kind="live"]   .kind-tag { background: var(--group-live); color: #264f3e; }
.catalog-item[data-kind="fresh"]  .kind-tag { background: var(--group-fresh); color: #3f575a; }
.catalog-item[data-kind="frozen"] .kind-tag { background: var(--group-frozen); color: #355166; }
.catalog-item[data-kind="other"]  .kind-tag { background: var(--group-other); color: var(--ink); }

/* the page titles carry the same face as "Available this week." */
.page-heading h1 { font-family: var(--title); font-weight: 400; letter-spacing: -.025em; }

/* Section headings on the public pages take the title face too, at the same
   size the feature card uses on the home page. Utility labels — "The weekly
   list", column heads — stay in the sans, so the two roles stay distinct. */
.contact-account h2,
.company-facts h2 { font-family: var(--title); font-weight: 400; font-size: 22px; letter-spacing: -.025em; }

/* Three across, then two, then one — all three kept together and in order, so
   the narrowest rule is always the last one to match. */
@media (max-width: 1180px) { .catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px)  { .catalog { grid-template-columns: minmax(0, 1fr); } }

/* the thumbnail is a button: it opens the photo at full size */
.catalog-shot {
  grid-column: 2; grid-row: 1 / -1; align-self: start;
  padding: 0; border: 0; background: none; line-height: 0; cursor: zoom-in;
  border-radius: 2px;
}
.catalog-shot img {
  width: 128px; height: auto; aspect-ratio: 16 / 9;
  object-fit: cover; display: block; background: var(--ice);
}
.catalog-shot:hover img { opacity: .88; }
.catalog-shot:focus-visible { outline: 3px solid #cf762d; outline-offset: 3px; }

/* --- the photo viewer ----------------------------------------------------- */

/* <dialog> + showModal() gives the focus trap, Escape and the inert background,
   which are the three things a hand-rolled lightbox usually gets wrong. */
.photo-dialog {
  border: 0; padding: 0; background: transparent;
  max-width: min(92vw, 720px); overflow: visible;
}
.photo-dialog::backdrop { background: rgba(23, 24, 26, .74); }
.photo-dialog figure { margin: 0; background: var(--white); border: 1px solid var(--rule); }
.photo-dialog img { width: 100%; height: auto; display: block; }
.photo-dialog figcaption { padding: 12px 16px; font-size: 14px; font-weight: 700; color: var(--ink); }

/* padding, margin and min-height are reset explicitly: the global button rule
   sets padding 12px var(--s5), and with border-box a width cannot fall below the
   padding it contains — that turned a 38px circle into a 57px oval. */
.photo-dialog .photo-close {
  position: absolute; top: 10px; right: 10px;
  width: 38px; height: 38px; min-height: 0; padding: 0; margin: 0;
  display: grid; place-items: center;
  border-radius: 50%; border: 1px solid rgba(0,0,0,.12);
  background: rgba(255,254,250,.94); color: var(--ink);
  font: 400 22px/1 var(--sans);
  box-shadow: 0 1px 4px rgba(0,0,0,.28);
  cursor: pointer;
}
.photo-dialog .photo-close:hover { background: #fff; }

@media (max-width: 620px) {
  /* The photo column is 96px on a phone and, as above, exists only on a card
     that has a photo. This rule used to give EVERY card the column, so a card
     with no photo lost a third of a 320px screen to nothing, and the name --
     beside a badge that does not shrink -- was squeezed to three lines with
     the badge pushed into the photograph. */
  .catalog-item:has(.catalog-shot) { grid-template-columns: minmax(0, 1fr) 96px; }
  .catalog-shot img { width: 96px; }
  /* Name and badge share a row while they fit; when they do not, the badge
     drops under the name instead of overflowing the column. */
  .catalog-head { flex-wrap: wrap; row-gap: 6px; }
  .catalog-head h2 { min-width: 0; }
  .photo-dialog .photo-close { top: 8px; right: 8px; }
}

/* --- Live List ------------------------------------------------------------ */

/* The quantity box is a 43px tap target, right on a phone in a kitchen and too
   generous on a desktop where a chef tabs down the list. Phones keep it. */

@media (min-width: 901px) {
  /* Tighter rows on a wide screen, but the side padding is the panel's and stays. */
  .lrow { padding: 7px var(--s4); }
  .lrow .nm { font-size: 15px; }
  .lrow .sub { font-size: 12px; margin-top: 1px; }
  .lrow input { min-height: 32px; padding: 4px 9px; }
}

/* Customer navigation: one desktop row, a mobile disclosure, and a native
   Account disclosure. Links retain their normal browser navigation behavior. */
body:not(.admin-app) .header-v2 { display:block; position:relative; z-index:20; border-top:3px solid var(--red); border-bottom:1px solid var(--edge); background:var(--white); }
body:not(.admin-app) .header-v2 .shell { width:min(1240px,calc(100% - 56px)); max-width:none; padding:0; margin-inline:auto; }
body:not(.admin-app) .header-v2 .masthead-inner { display:flex; align-items:center; flex-wrap:nowrap; gap:28px; min-height:86px; }
body:not(.admin-app) .header-v2 .brand { flex-shrink:0; }
body:not(.admin-app) .header-v2 .masthead-note { margin:0; flex-shrink:0; }
body:not(.admin-app) .header-v2 .site-navigation { display:flex; align-items:center; justify-content:flex-end; gap:28px; margin-left:auto; min-width:0; }
body:not(.admin-app) .header-v2 .site-navigation[hidden] { display:none; }
body:not(.admin-app) .header-v2 .navigation { display:flex; align-items:center; gap:26px; width:auto; margin:0; padding:0; background:none; border:0; }
body:not(.admin-app) .header-v2 .navigation a { display:flex; position:relative; align-items:center; flex:none; min-height:44px; padding:0; border:0; background:none; color:var(--muted); font:400 14px/1.3 var(--sans); white-space:nowrap; text-decoration:none; }
body:not(.admin-app) .header-v2 .navigation a::before { content:none; }
body:not(.admin-app) .header-v2 .navigation a::after { content:none; }
body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on) { color:var(--ink); font-weight:600; }
body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on)::after { content:''; position:absolute; left:0; right:0; bottom:1px; height:2px; background:var(--red); }
body:not(.admin-app) .header-v2 .navigation a:hover { color:var(--red); background:none; }
body:not(.admin-app) .header-v2 .headright { display:flex; align-items:center; align-self:center; gap:20px; margin:0; padding:0; flex-shrink:0; }
body:not(.admin-app) .header-v2 .headright > .signin { display:inline-flex; justify-content:center; align-items:center; min-height:44px; padding:11px 18px; margin:0; background:var(--red); color:var(--white); border:1px solid var(--red); border-radius:0; font:600 14px/1.3 var(--sans); text-decoration:none; white-space:nowrap; }
body:not(.admin-app) .header-v2 .headright > .signin:hover { background:#8e301e; border-color:#8e301e; }
body:not(.admin-app) .header-v2 .account-menu { position:relative; margin:0; padding:0; border:0; background:none; font:400 14px/1.4 var(--sans); }
body:not(.admin-app) .header-v2 .account-menu[hidden] { display:none; }
body:not(.admin-app) .header-v2 .account-menu > summary { display:flex; align-items:center; gap:10px; min-height:44px; padding:0 2px; margin:0; list-style:none; color:var(--ink); font:400 14px/1.4 var(--sans); cursor:pointer; }
body:not(.admin-app) .header-v2 .account-menu > summary::-webkit-details-marker { display:none; }
body:not(.admin-app) .header-v2 .account-menu > summary::after { content:''; width:6px; height:6px; margin-top:-3px; border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor; transform:rotate(45deg); }
body:not(.admin-app) .header-v2 .account-menu[open] > summary::after { transform:rotate(225deg); margin-top:3px; }
body:not(.admin-app) .header-v2 .account-menu .account-nav { position:absolute; z-index:30; right:0; top:calc(100% + 8px); display:flex; flex-direction:column; align-items:stretch; gap:0; width:210px; max-width:calc(100vw - 28px); padding:6px; margin:0; border:1px solid var(--edge); border-top:2px solid var(--navy); background:var(--white); box-shadow:0 8px 20px #1235431a; }
body:not(.admin-app) .header-v2 .account-menu:not([open]) .account-nav { display:none; }
body:not(.admin-app) .header-v2 .account-nav a { display:block; min-height:44px; padding:12px; margin:0; border:0; color:var(--ink); background:none; font:400 14px/1.3 var(--sans); text-decoration:none; white-space:normal; }
body:not(.admin-app) .header-v2 .account-nav a:hover, body:not(.admin-app) .header-v2 .account-nav a:is(.on,[aria-current="page"]) { background:var(--paper); color:var(--red); }
body:not(.admin-app) .header-v2 .account-nav a:last-child { border-top:1px solid var(--edge); }
body:not(.admin-app) .header-v2 .site-menu-toggle { display:none; }
@media(max-width:1160px) {
  body:not(.admin-app) .header-v2 .masthead-note { display:none; }
}
@media(max-width:1120px) {
  body:not(.admin-app) .header-v2 .shell { width:calc(100% - 36px); }
  body:not(.admin-app) .header-v2 .site-navigation { gap:22px; }
  body:not(.admin-app) .header-v2 .navigation { gap:22px; }
}
@media(max-width:760px) {
  body:not(.admin-app) .header-v2 .shell { width:calc(100% - 28px); }
  body:not(.admin-app) .header-v2 .masthead-inner { flex-wrap:wrap; gap:0 16px; min-height:76px; padding-block:6px; }
  /* The phone header, 14 September 2026, the owner's own design: "move the
     sign in to where menu button is and always show the menu."

     No Menu button. Sign in sits top-right beside the logo, where Menu was,
     and the three links are a full-width row beneath -- always there, equal
     segments, the current page underlined in red. Nothing to open.

     display:contents lifts .navigation and .headright out of their wrapper
     so the masthead's own wrap can put one beside the logo and the other on
     its own row. A cached page still carrying the old button gets it hidden. */
  body:not(.admin-app) .header-v2 .site-menu-toggle { display:none !important; }
  body:not(.admin-app) .header-v2 .site-navigation,
  body:not(.admin-app) .header-v2 .site-navigation[hidden] { display:contents; }
  body:not(.admin-app) .header-v2 .headright { order:0; align-self:center; margin:0 0 0 auto; padding:0; gap:10px; flex-wrap:nowrap; }
  body:not(.admin-app) .header-v2 .headright > .signin { min-height:44px; padding:10px 16px; font-size:14px; }
  body:not(.admin-app) .header-v2 .headright > .account-menu:not([hidden]) { flex:0 0 auto; }
  body:not(.admin-app) .header-v2 .navigation { order:1; flex:1 0 100%; flex-direction:row; align-items:stretch; justify-content:space-between; gap:0; margin:6px 0 0; border-top:1px solid var(--edge); }
  body:not(.admin-app) .header-v2 .navigation a { flex:1 1 0; justify-content:center; min-height:46px; padding:0 4px; border-bottom:2px solid transparent; color:var(--ink); font-size:15px; white-space:nowrap; }
  body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on) { color:var(--red); border-bottom-color:var(--red); font-weight:600; }
  body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on)::after { content:none; }
}

/* Allow a full cutoff date to wrap on narrow phones rather than clip. */
@media (max-width: 520px) {
  .week-page { padding-inline: 14px; }
  .week-arrival { flex-shrink: 1; flex-wrap: wrap; width: 100%; max-width: 100%; gap: 8px 18px; }
  .week-arrival > div { min-width: 0; }
  .week-arrival strong { white-space: normal; }
}

/* --- Phones: readable first, dense second ---------------------------------
   The owner, on his phone, 11 September 2026: "it feels we are too small ...
   I am unable to read it." Measured at 375px: the ARRIVES / CLOSED captions
   were 10px, the origin line 11px, "Southern California, wild" and the
   Product details link 12px. The phone breakpoints above were written to
   keep the list on the first screen, and paid for it in type size. That
   trade is reversed here: nothing a person is expected to read is below
   14px, nothing they tap is below 15px, and uppercase tracked labels -- which
   read larger than their size -- stop at 12px. The page gets longer. That
   is fine; a phone scrolls.

   This block is last so it wins every earlier phone rule without editing
   them. It touches the public pages only: the desk has its own stylesheet. */
@media (max-width: 620px) {
  /* Uppercase, tracked labels: 10-11px -> 12px. */
  .eyebrow, .label, .kicker, .lbl, .list-head, .group-head > span,
  .feature .overline, .week-arrival .caption, .landing-strip .label,
  .facts-list dt, .footer-brand span, .legal, .live-word,
  thead th, tbody th, .doclines thead th { font-size: 12px; }

  /* The week list. */
  .row-name { font-size: 16px; }
  .row-origin, .row-origin span { font-size: 14px; line-height: 1.4; }
  /* "box" on its own line under "25 lb box" was the pack label rendered a
     second time as a column of its own. The description already says it. */
  .row-unit { display: none; }
  .row .status, .status, .status-note, .catalog-item .status,
  .catalog-item .status-note, .orow .status { font-size: 13px; padding: 5px 9px; }

  /* The arrival strip. */
  .week-arrival strong, #landing-date, #cutoff-date { font-size: 17px; }

  /* The feature card. Bigger title, readable source line, a link that can be
     hit with a thumb. */
  .feature h2 { font-size: 21px; line-height: 1.15; }
  .feature-source, .feature-facts { font-size: 14px; }
  /* .feature-bottom .text-action is the more specific rule above; name it. */
  .feature-bottom .text-action { font-size: 15px; padding: 4px 0; white-space: nowrap; }
  /* The link and the badge no longer fit side by side at this size; stack
     them rather than let the link break into three lines. */
  .feature-bottom { flex-wrap: wrap; row-gap: 6px; }
  .feature-bottom .status { white-space: nowrap; }

  /* The products page and the rest. */
  .catalog-item .catalog-meta, .catalog-item .catalog-season, .catalog-item details,
  .product-photo figcaption, .heading-note, .result-count, .feed-state,
  .board-note, .help, .small { font-size: 14px; }
  .facts-list dd, .contact-primary p, .service-area { font-size: 15px; }
  .phone { font-size: 20px; }
  .lqty .unit, .lrow .pr small { font-size: 13px; }
  /* The products page: the LIVE / FRESH / FROZEN tag was 10px, the latin name
     and the "Looking for something else?" line 12-13px. */
  .kind-tag { font-size: 12px; }
  .catalog-item .catalog-latin, .catalog-item p, .order-bar p, .search-wrap label { font-size: 14px; }
  /* The order confirmation -- what a customer opens from the email. It had no
     phone rules at all: a 4-column meta grid, a 110px seal beside the company
     block, and a five-column lines table with nowrap money columns, which on a
     375px screen pushed the whole page past the viewport and cut the left edge
     off. The owner opened one on a phone on 14 September 2026 and saw
     "er confirmation". */
  .doc { padding: var(--s4) var(--s3); margin: var(--s4) 0 var(--s6); }
  .dochead { flex-direction: column; align-items: flex-start; gap: var(--s3); }
  .doclogo { width: 200px; height: auto; }
  .dochead .doctitle { text-align: left; }
  .docfootseal { width: 96px; height: 96px; border-radius: 50%; }
  .doctitle { font-size: 24px; margin: var(--s4) 0 var(--s3); }
  .docmeta { grid-template-columns: 1fr 1fr; gap: var(--s3) var(--s4); }
  .docmeta .k { font-size: 12px; }
  .docmeta .v { font-size: 15px; }
  /* Each line becomes a labelled block (table.resp above). The item cell is
     the heading of its block, so it reads left and carries no label. */
  .doclines td.item { display: block; text-align: left; padding-bottom: 6px; }
  .doclines td.item::before { content: none; }
  .doclines .num { white-space: normal; font-size: 14px; }
  .doclines .sub { font-size: 13px; }
  .doctotal { font-size: 19px; }
  .doc-actions { gap: var(--s3); }
  .doc-actions a, .doc-actions button { font-size: 15px; }

  /* Anything a thumb presses. The account-request button is the one
     conversion on the site and was 13px. */
  .button, .btn, .quiet-link, .text-link, .text-action, button[type=submit] { font-size: 15px; }
  .contact-account .button { padding: 12px 18px; }
}


/* ==========================================================================
   8. Peak Seafood, navy — approved 23 September 2026
      (brand-assets/peak-seafood-blue-web-handoff-2026-09-23/integration/peak-blue.css)

   Last on purpose: it re-tokenises the palette and overrides the header and
   footer geometry above. The brand accent is dark navy; --red is left alone
   because errors, sold-out, collect-at-the-door and destructive actions still
   mean red. The button rule is scoped to body:not(.admin-app) and to a.button,
   so the desk keeps its own buttons.
   ========================================================================== */
:root {
  --accent: #123543;
  --accent-hover: #0D2833;
  --navy: #123543;
  --navy-deep: #0D2833;
  --paper: #F3EDE1;
  --group-live: #D4E5EB;
  --group-fresh: #E4EEEF;
  --group-frozen: #BDCFDB;
}
/* Scope decorative brand colors. Preserve the legacy --red token because
   existing error/warning messages also use it. Do not recolor seafood photos. */
body:not(.admin-app) .header-v2 { border-top-color:var(--accent); background:var(--paper); }
body:not(.admin-app) .header-v2 .masthead { background:var(--paper); }
body:not(.admin-app) .header-v2 .masthead-inner { min-height:118px; padding-block:12px; gap:24px; }
body:not(.admin-app) .header-v2 .brand { width:320px; height:auto; }
body:not(.admin-app) .header-v2 .brand .headlogo { display:block; width:100%; height:auto; max-height:none; }
.brand picture { display:block; width:100%; }
body:not(.admin-app) .header-v2 .headright > .signin { background:var(--accent); border-color:var(--accent); }
body:not(.admin-app) .header-v2 .headright > .signin:hover { background:var(--accent-hover); border-color:var(--accent-hover); }
body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on)::after { background:var(--accent); }
body:not(.admin-app) .header-v2 .navigation a:hover,
body:not(.admin-app) .header-v2 .account-nav a:hover,
body:not(.admin-app) .header-v2 .account-nav a:is(.on,[aria-current="page"]),
.masthead-note a:hover { color:var(--accent); }
/* Public action links only; admin and semantic action buttons retain their
   existing styles. Keep error, sold-out, collect-at-door and delete states. */
body:not(.admin-app) a.button:not(.danger):not(.delete):not(.destructive):not(.error) { background:var(--accent); }
body:not(.admin-app) a.button:not(.danger):not(.delete):not(.destructive):not(.error):hover { background:var(--accent-hover); }
body:not(.admin-app) .eyebrow, body:not(.admin-app) .kicker,
body:not(.admin-app) .feature h2 span { color:var(--accent); }
body:not(.admin-app) .feature, body:not(.admin-app) .row-signature { border-top-color:var(--accent); border-left-color:var(--accent); }
body:not(.admin-app) .row-signature .row-name { color:var(--accent); }
body:not(.admin-app) .catalog-item.targeted { outline-color:var(--accent); }
body:not(.admin-app) .navigation a[aria-current=page]:after, body:not(.admin-app) .navigation a.on:after { background:var(--accent); }
footer.site { background:var(--navy); }
.footer-brand { gap:24px; }
.footer-brand .peak-circle { width:200px; flex:0 0 200px; display:block; }
.footer-brand .peak-circle img { display:block; width:100%; height:auto; aspect-ratio:1; border-radius:50%; object-fit:contain; }
.footer-brand p { font-family:var(--title); font-size:28px; font-weight:400; line-height:1.2; }
.footer-brand span { font-family:var(--sans); font-size:15px; line-height:1.5; margin-top:6px; }
@media (max-width:1100px) {
  body:not(.admin-app) .header-v2 .masthead-note { display:none; }
}
@media (max-width:760px) {
  body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on) { color:var(--accent); border-bottom-color:var(--accent); }
  .footer-inner { flex-wrap:wrap; gap:16px 24px; }
  .footer-brand { flex-basis:100%; }
  .footer-brand .peak-circle { width:180px; flex-basis:180px; }
  .footer-brand p { font-size:25px; }
}
@media (max-width:620px) {
  /* Give the wide swimming logo its own row; preserve a readable SEAFOOD. */
  body:not(.admin-app) .header-v2 .masthead-inner { flex-wrap:wrap; gap:10px; padding-block:12px 0; }
  body:not(.admin-app) .header-v2 .brand { width:260px; height:auto; margin-inline:auto; }
  body:not(.admin-app) .header-v2 .brand .headlogo { width:100%; height:auto; }
  body:not(.admin-app) .header-v2 .site-navigation,
  body:not(.admin-app) .header-v2 .site-navigation[hidden] { display:flex; flex:1 0 100%; width:100%; gap:12px; align-items:center; border-top:1px solid var(--edge); }
  body:not(.admin-app) .header-v2 .navigation { order:0; flex:1 1 auto; width:auto; border:0; gap:8px; margin:0; }
  body:not(.admin-app) .header-v2 .navigation a { font-size:13px; padding:0; flex:1 1 auto; min-height:48px; }
  body:not(.admin-app) .header-v2 .navigation a:is([aria-current="page"],.on) { color:var(--accent); border-bottom-color:var(--accent); }
  body:not(.admin-app) .header-v2 .headright { flex:0 0 auto; margin:0; }
  body:not(.admin-app) .header-v2 .headright > .signin { font-size:13px; padding:10px; min-height:44px; }
  .footer-brand { flex-direction:column; align-items:flex-start; gap:16px; }
}


/* ==========================================================================
   9. The footer, centred, with the two-peak seal — approved 23 September 2026
      (brand-assets/peak-seafood-right-fish-two-peaks-2026-09-23)

   The outside columns are equal 1fr tracks so the circle sits on the PAGE's
   centre line rather than on the midpoint of whatever space is left over.
   That is the whole reason this is a grid and not a flex row.

   Block is Big Shoulders. The build has always shipped it -- copy-fonts.cjs
   maps big-shoulders-latin-700 to /fonts/block-bold.woff2 -- but nothing ever
   declared it, so it was 14kB nobody could use. The package set this line in
   Georgia; the owner asked for the site's own faces, and this is the face the
   PEAK lettering is drawn from, so the footer name is set in it.

   The seal keeps its painted paper ground and is clipped with border-radius,
   never a filter: the painting must not be altered.
   ========================================================================== */
@font-face { font-family: Block; src: url(/fonts/block-bold.woff2) format('woff2'); font-weight: 700; font-display: swap; }
:root { --block: Block, 'Big Shoulders Display', var(--sans); }
footer.site.footer-centered { background:#123543; color:#F3EDE1; }
footer.site.footer-centered .footer-inner {
  display:grid;
  grid-template-columns:minmax(0,1fr) 200px minmax(0,1fr);
  grid-template-areas:"brand seal contact";
  align-items:center;
  gap:32px;
  width:min(1240px,calc(100% - 64px));
  max-width:none;
  margin-inline:auto;
  padding:30px 0;
}
footer.site.footer-centered .footer-brand {
  grid-area:brand; display:block; min-width:0; margin:0; text-align:left;
}
footer.site.footer-centered .footer-brand p {
  margin:0; font:700 28px/1.15 var(--block); letter-spacing:.015em; text-transform:uppercase;
}
footer.site.footer-centered .footer-brand span {
  /* Only the name is set in the display face and uppercased; the descriptor
     stays sentence case in Plex, the way it reads everywhere else. */
  display:block; margin-top:7px; color:#b7cbd0; text-transform:none; letter-spacing:0;
  font:400 14px/1.5 var(--sans,Arial,sans-serif);
}
footer.site.footer-centered .peak-circle {
  grid-area:seal; display:block; width:200px; margin:0; justify-self:center;
}
footer.site.footer-centered .peak-circle img {
  display:block; width:100%; height:auto; aspect-ratio:1; border-radius:50%; object-fit:contain;
}
footer.site.footer-centered .footer-contact {
  grid-area:contact; display:flex; flex-direction:column; align-items:flex-end;
  justify-self:end; min-width:0; gap:4px; text-align:right;
}
footer.site.footer-centered .footer-contact > a {
  display:inline-flex; align-items:center; min-height:44px;
  color:inherit; font-size:14px; text-decoration:none; white-space:nowrap;
}
footer.site.footer-centered .legal {
  display:flex; justify-content:flex-end; gap:20px; margin:0; font-size:12px;
}
footer.site.footer-centered .legal a {
  display:inline-flex; align-items:center; min-height:44px; padding:0;
  color:#c9d7da; text-decoration:none;
}
footer.site.footer-centered a:hover { text-decoration:underline; text-underline-offset:4px; }
footer.site.footer-centered a:focus-visible { outline:2px solid #F3EDE1; outline-offset:4px; }
@media(max-width:760px) {
  footer.site.footer-centered .footer-inner {
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:"seal" "brand" "contact";
    width:calc(100% - 32px); gap:20px; padding-block:28px;
  }
  footer.site.footer-centered .peak-circle { width:180px; }
  footer.site.footer-centered .footer-brand { text-align:center; }
  footer.site.footer-centered .footer-brand p { font-size:26px; }
  footer.site.footer-centered .footer-contact { justify-self:center; align-items:center; text-align:center; }
  footer.site.footer-centered .legal { justify-content:center; }
}

/* ===========================================================================
   10. Solid header wordmark and shared Colorado mountains — 23 September 2026

   The approved smaller mountain backdrop is a separate transparent layer.
   Its 48% opacity leaves the solid navy lettering clear. The footer uses the
   same mountain illustration at 48%. Keep this public-header styling
   scoped so the admin shell and printed documents retain their own layouts.
   ========================================================================== */
body:not(.admin-app) .header-v2.peak-mountain-header { background:#F3EDE1; border-top-color:var(--accent); }
body:not(.admin-app) .header-v2.peak-mountain-header .masthead { background:#F3EDE1; }
body:not(.admin-app) .header-v2.peak-mountain-header .shell { width:min(1400px,calc(100% - 64px)); max-width:none; margin-inline:auto; padding-inline:26px; }
body:not(.admin-app) .header-v2.peak-mountain-header .masthead-inner { min-height:118px; padding-block:12px; gap:24px; }
body:not(.admin-app) .header-v2.peak-mountain-header .brand { width:238.425px; height:auto; margin-inline:0; flex-shrink:0; }
body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-art { display:block; position:relative; isolation:isolate; width:100%; height:94px; }
body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-mountains { display:block; position:absolute; z-index:0; left:0; top:-1px; width:238.425px; height:79.475px; opacity:.48; pointer-events:none; }
body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-mountains img { display:block; width:100%; height:100%; max-width:none; }
body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-wordmark { display:block; position:absolute; z-index:1; left:50%; top:0; transform:translateX(-50%); width:147.882845px; height:94px; }
body:not(.admin-app) .header-v2.peak-mountain-header .brand .headlogo { display:block; width:100%; height:94px; max-width:none; max-height:none; }
@media(max-width:900px) {
  body:not(.admin-app) .header-v2.peak-mountain-header .shell { padding-inline:16px; }
}
@media(max-width:760px) {
  body:not(.admin-app) .header-v2.peak-mountain-header .shell { width:calc(100% - 36px); }
}
@media(max-width:620px) {
  body:not(.admin-app) .header-v2.peak-mountain-header .masthead-inner { flex-wrap:wrap; gap:10px; padding-block:12px 0; }
  body:not(.admin-app) .header-v2.peak-mountain-header .brand { width:190.74px; }
  body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-art { height:76.375px; }
  body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-mountains { width:190.74px; height:63.58px; top:-.8px; }
  body:not(.admin-app) .header-v2.peak-mountain-header .peak-header-wordmark { width:120.150628px; height:76.375px; }
  body:not(.admin-app) .header-v2.peak-mountain-header .brand .headlogo { height:76.375px; }
}
@media(max-width:520px) {
  body:not(.admin-app) .header-v2.peak-mountain-header .shell { padding-inline:14px; }
}
@media(max-width:350px) {
  body:not(.admin-app) .header-v2.peak-mountain-header .shell { width:calc(100% - 28px); }
}

/* ===========================================================================
   FORM BOXES ON A PHONE ARE 16px — 16 September 2026

   A box a person types into is at least 16px on a phone. Below that, iOS
   Safari zooms the whole page in when the box is tapped and leaves it zoomed
   when the typing is done; every desk screen used from the van had it. The
   base rule above already says 16px for input, select and textarea, but a
   page can shrink one with a class (the stop-number box on the Deliveries
   screen did, to 15px). This rule is written to outrank a class on the
   element and every later rule, so a page cannot undo it by accident. Checkboxes and radios are
   drawn by the browser and are not typed into. It is the one !important in
   this file, and it is a floor: a floor that a later two-class rule can
   quietly undo is not a floor.

   tests/phone-form-boxes.test.cjs fails the build on any form box under 16px
   at phone width; the 390px sweep measures the real thing. */
@media (max-width: 620px) {
  input:not([type=checkbox]):not([type=radio]), select, textarea { font-size: 16px !important; }
}
