/*
 * Copyright © 1996 - 2026 Gousse & Gousse Inc. or its Affiliates., All Rights Reserved.
 *  author: Al D. Gousse
 *    site: www.goussecorp.com
 *   email: info@goussecorp.com
 *  twitter: @goussecorp
 **/

/* Public-facing brand identity (landing page, and eventually the rest of
   the storefront) — deliberately separate from style.css, which stays the
   plain, efficient admin-tool look. Implements the heraldic/coat-of-arms,
   red-and-gold, serif direction decided in planning/branding.md.

   Uses only OS-installed serif fonts (Georgia/Garamond/Times New Roman)
   rather than a webfont — the app's Content-Security-Policy is
   `default-src 'self'` (see security.rs), so pulling a font from Google
   Fonts or any other CDN would be silently blocked by the browser anyway.
   A real illustrated crest/logo is a future asset task; the seal below is
   a CSS-drawn placeholder monogram, not finished artwork. */

.brand-page {
  --crest-red: #7a1620;
  --crest-red-dark: #551018;
  --crest-gold: #c9a227;
  --crest-gold-light: #e3c567;
  --crest-cream: #f6f1e7;
  --crest-ink: #2a1a12;

  /* Added for the 2026-07 "BonSelle" leather/equestrian redesign
     (planning/branding.md history above is heraldic red/gold; these two
     extend the same family with warmer, material-coded tones so cards,
     badges, and panels can read as "leather goods" rather than generic
     retail without introducing a whole new palette). --leather-tan is a
     saddle/cognac hide tone used sparingly for warm fills (badges, subtle
     section backgrounds); --leather-shadow is a soft warm-brown shadow
     color (replaces default black box-shadows, which read cold/generic
     against this palette). */
  --leather-tan: #b06a3a;
  --leather-tan-light: #f2e3d3;
  --leather-shadow: 26, 16, 10;

  /* Shared radius + easing so every card/button/panel in the redesign
     rounds and moves the same amount instead of an ad hoc mix of 0/2px/
     6px corners inherited from three different CSS eras (brand.css,
     shop.css, style.css). */
  --brand-radius: 4px;
  --brand-ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  /* Darker than --crest-gold specifically for borders/rules on light
     backgrounds: --crest-gold itself is only ~2.2-2.4:1 against white/
     cream, under WCAG 1.4.11's 3:1 minimum for UI-component boundaries.
     --crest-gold stays as-is for text/accent use (e.g. against dark
     backgrounds, or decorative, non-boundary-defining uses) where that
     specific failure mode doesn't apply. */
  --crest-gold-border: #a5842a;

  background: var(--crest-cream);
  color: var(--crest-ink);
  font-family: Garamond, Georgia, "Times New Roman", serif;
  font-size: 16.5px;
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

.brand-page h1,
.brand-page h2,
.brand-page h3 {
  font-weight: 400;
  letter-spacing: 0.01em;
}

/* ---------- Storefront form controls ----------
   Every storefront form (search/sort on shop_list, quantity/variant
   selects on shop_detail, login/register/checkout/account) was falling
   through to style.css's generic admin-tool input styling: flat gray
   borders and a stock blue focus ring (--focus: #2563eb) that has no
   relationship to this page's cream/ink/gold identity. Scoped to
   .brand-page rather than changed globally in style.css, which stays the
   admin panel's own plain look on purpose (same reasoning as the
   .grid-container/.button overrides above). */
.brand-page input[type="text"],
.brand-page input[type="email"],
.brand-page input[type="password"],
.brand-page input[type="number"],
.brand-page input[type="search"],
.brand-page input[type="tel"],
.brand-page input[type="date"],
.brand-page select,
.brand-page textarea {
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  background: #fff;
  color: var(--crest-ink);
  font-family: inherit;
  padding: 0.6rem 0.75rem;
}

.brand-page input:focus,
.brand-page select:focus,
.brand-page textarea:focus {
  outline: 2px solid var(--crest-red-dark);
  outline-offset: 1px;
}

.brand-page label {
  color: var(--crest-ink);
  font-weight: 600;
  font-size: 0.88rem;
  letter-spacing: 0.02em;
}

.brand-page fieldset {
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  background: rgba(255, 255, 255, 0.5);
  padding: 1.1rem 1.35rem 1.35rem;
  margin: 0 0 1.5rem;
}

.brand-page legend {
  color: var(--crest-red-dark);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  padding: 0 0.5rem;
}

.brand-page table.table,
.brand-page table {
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  overflow: hidden;
  border-collapse: separate;
  border-spacing: 0;
}

.brand-page table.table thead th,
.brand-page table thead th {
  background: var(--leather-tan-light);
  color: var(--crest-red-dark);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.75rem;
  font-weight: 700;
  border-bottom: 1px solid var(--crest-gold-border);
}

.brand-page table.table td,
.brand-page table.table th,
.brand-page table td,
.brand-page table th {
  border-bottom: 1px solid #ece3d0;
  padding: 0.75rem 0.9rem;
}

.brand-page table.table tbody tr:last-child td,
.brand-page table tbody tr:last-child td {
  border-bottom: none;
}

.brand-page [role="alert"],
.brand-page .callout.alert {
  background: #fbeceb;
  border: 1px solid #d99b91;
  color: var(--crest-red-dark);
  border-radius: var(--brand-radius);
}

.brand-page .callout.success {
  background: #edf5e6;
  border: 1px solid #9fc47c;
  color: #33511f;
  border-radius: var(--brand-radius);
}

.brand-page .callout.warning {
  background: var(--leather-tan-light);
  border: 1px solid var(--leather-tan);
  color: #6b3d13;
  border-radius: var(--brand-radius);
}

/* Foundation's `.grid-container` defaults to a centered 75rem (1200px) cap
   -- fine for the admin panel's forms/tables (still uses that default,
   untouched here), but on a wide desktop it left the storefront's product
   grid and shop sidebar sitting in a centered island with equal dead
   margins on both sides, while the header/subnav above already run full
   width. Scoped to .brand-page only so admin screens keep Foundation's
   stock behavior -- this makes every 12-column grid on the storefront
   (shop_list.html's 3+9 sidebar/content split, the product-card grid,
   etc.) actually divide the full viewport width instead of a capped
   center column. */
.brand-page .grid-container {
  max-width: 100%;
}

/* Foundation's own .button component (Add to cart, checkout actions, etc.)
   restyled to the same outlined-uppercase look as .brand-cta, scoped to
   .brand-page rather than overridden globally — the admin panel also
   loads foundation.css and deliberately keeps its own plain, filled-button
   look (see the note above), so a global Foundation button override would
   have bled into admin pages too. `:not(.alert)` deliberately excludes
   cart.html's "Remove" line-item button (class="button small alert") from
   the flat treatment — that's a destructive action and needs to keep
   reading differently from "Update"/"Proceed to checkout", not get
   flattened to look identical to them. */
.brand-page .button:not(.alert) {
  background: transparent;
  color: var(--crest-ink);
  border: 1px solid var(--crest-ink);
  border-radius: 0;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
}

.brand-page .button:not(.alert):hover,
.brand-page .button:not(.alert):focus {
  background: var(--crest-ink);
  color: var(--crest-cream);
}

/* Restyled 2026-07-18 to the Hancocks Signet Rings reference look
   (planning/branding.md): white/cream background instead of a bold color
   banner, a single thin gold rule as the only strong color accent, and
   restrained typography. Logo stays left-aligned (the one deliberate
   deviation from the reference, which centers its wordmark) — the DOM
   order here (mark, search, qr, icons) with `justify-content:
   space-between` already put it there, so no markup change was needed. */
.brand-header {
  background: var(--crest-cream);
  border-bottom: 1px solid var(--crest-gold-border);
  padding: 1.1rem 1.75rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.brand-mark {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  text-decoration: none;
  flex-shrink: 0;
}

/* CSS-drawn placeholder seal: a gold-ringed medallion with an initial
   monogram. Stands in for real heraldic artwork until that's commissioned. */
.brand-seal {
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: var(--crest-cream);
  border: 1.5px solid var(--crest-gold);
  color: var(--crest-red);
  font-weight: 700;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.brand-mark-text {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.brand-name {
  color: var(--crest-ink);
  font-size: 1.4rem;
  letter-spacing: 0.08em;
  font-weight: 400;
  text-transform: uppercase;
}

.brand-est {
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--crest-red-dark);
  margin-top: 0.15rem;
}

/* Centered search bar — `flex: 1` with a max-width keeps it from
   stretching edge-to-edge on wide screens while still centering between
   the logo and the icon group on either side.
   `.brand-search` is a <form>, and style.css's generic `form { background,
   padding: 1.25rem 1.5rem, border, box-shadow }` rule (styled for the admin
   tool's forms) applies to every <form> on the page including this one —
   without resetting those properties here, that admin panel styling shows
   through as a large white box around the search bar. */
.brand-search {
  flex: 1 1 20rem;
  max-width: 32rem;
  display: flex;
  align-items: center;
  margin: 0 1rem;
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
}

/* Fixed `height` (rather than padding alone) on both the input and the
   button keeps them the same slim height as each other regardless of font
   metrics, instead of relying on padding to happen to line up.
   `box-sizing`/`appearance`/`margin`/`line-height` are reset explicitly on
   the button because browsers give native <button> elements hidden default
   sizing (e.g. Firefox's internal focus-padding) that doesn't shrink to fit
   an explicit `height` the same predictable way an <input> does — without
   this reset the button renders visibly taller than the input next to it. */
.brand-search input[type="search"] {
  flex: 1;
  box-sizing: border-box;
  height: 1.9rem;
  /* Foundation's default form-input reset gives every <input> a
     `margin: 0 0 1rem 0`, never cleared for this one specifically. Since
     `.brand-search` centers its children with `align-items: center`, that
     leftover 16px bottom margin was stretching the flex container's cross-
     size to the input's full margin box (46px) while the button next to it
     had no margin (30px) -- centering the button within that taller box
     pushed it 8px lower than the input, so its bottom edge stuck out below
     the input's visible border. Confirmed via direct measurement of both
     elements' rendered boxes, not guessed. */
  margin: 0;
  border: 1px solid var(--crest-gold-border);
  border-right: none;
  border-radius: 0;
  padding: 0 0.6rem;
  font-family: inherit;
  font-size: 0.85rem;
  background: #fff;
  color: var(--crest-ink);
}

.brand-search input[type="search"]:focus {
  outline: 2px solid var(--crest-red-dark);
  outline-offset: 0;
}

/* Browser default placeholder color is a washed-out light gray that's hard
   to read against the white input background. */
.brand-search input[type="search"]::placeholder {
  color: #6b6558;
  opacity: 1;
}

/* Outlined, not filled — matches the reference's restrained button
   treatment (see .brand-cta below, which switched the same way). */
.brand-search button {
  box-sizing: border-box;
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  line-height: 1;
  height: 1.9rem;
  border: 1px solid var(--crest-gold-border);
  border-radius: 0;
  background: #fff;
  color: var(--crest-ink);
  padding: 0 0.7rem;
  cursor: pointer;
  display: flex;
  align-items: center;
}

/* Firefox adds hidden internal focus-padding inside native buttons that
   the rules above can't reach — without this it can still render a touch
   taller/wider than the height set above. */
.brand-search button::-moz-focus-inner {
  border: 0;
  padding: 0;
}

.brand-search button:hover {
  background: var(--crest-cream);
  color: var(--crest-red);
}

.brand-search button:focus {
  outline: 2px solid var(--crest-red-dark);
  outline-offset: 1px;
}

.brand-icons {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-shrink: 0;
}

/* Sits between the search bar and the cart/sign-in icons — gives the
   header a third visual anchor point instead of leaving that stretch of
   the bar looking sparse. Links to the real production URL, not
   whichever host happens to be serving this dev instance (see
   `QR_TARGET_URL` in main.rs). */
.brand-qr {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  color: var(--crest-ink);
  flex-shrink: 0;
}

.brand-qr img {
  width: 2.75rem;
  height: 2.75rem;
  background: #fff;
  border: 1px solid var(--crest-gold);
  padding: 2px;
}

.brand-qr-label {
  font-size: 0.7rem;
  line-height: 1.25;
  letter-spacing: 0.02em;
}

.brand-locale {
  position: relative;
}

/* Reset for the same reason as `.brand-search`/`.product-card form` —
   style.css's generic `button { margin-top, padding, border-radius,
   background: var(--accent), color: #fff }` rule applies to any <button>
   on the page, and `.brand-icon-link` (shared with the Cart/Sign In <a>
   tags) never needed to override those since anchors don't pick up
   button styling. */
/* Stacked (icon above label) rather than the row layout `.brand-icon-link`
   normally uses for Cart/Sign In — this one has more text ("EN / USD")
   than a one-word label, so stacking keeps it from getting too wide next
   to the QR block and the other icons. */
#brand-locale-toggle {
  background: none;
  border: none;
  margin: 0;
  padding: 0;
  border-radius: 0;
  font: inherit;
  flex-direction: column;
  gap: 0.2rem;
}

#brand-locale-toggle .brand-icon-label {
  font-size: 0.65rem;
}

.brand-locale-menu {
  position: absolute;
  top: calc(100% + 0.6rem);
  right: 0;
  z-index: 50;
  width: 17rem;
  background: var(--crest-cream, #f6f1e7);
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  padding: 0.85rem;
  color: var(--crest-ink, #2a1a12);
  text-align: left;
}

.brand-locale-note {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--crest-red-dark);
  margin: 0 0 0.75rem;
}

/* Labeled dropdown field, stacked vertically — one for Language, one for
   Currency (the Currency `<select>` groups its options into Caribbean/
   North America/South America via `<optgroup>`). */
.brand-locale-field {
  margin-top: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.brand-locale-field:first-of-type {
  margin-top: 0;
}

.brand-locale-field label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--crest-red-dark);
}

.brand-locale-field select {
  width: 100%;
  padding: 0.4rem 0.5rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--crest-ink, #2a1a12);
  background: #fff;
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
}

#brand-locale-save {
  display: block;
  width: 100%;
  margin-top: 1rem;
  text-align: center;
}

/* Icon + label sit side by side on one line rather than stacked — stacking
   them was what made the header read as too tall/thick. */
.brand-icon-link {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  color: var(--crest-ink);
  text-decoration: none;
}

.brand-icon-link:hover {
  color: var(--crest-red);
}

/* Header/subnav backgrounds are light now (cream/white), so a dark outline
   gives the strongest contrast — gold (~2.2:1 against cream) would fail the
   3:1 WCAG 1.4.11 minimum for a focus indicator on this light background,
   unlike the old dark-red header it used to sit on. Deliberately scoped to
   specific selectors rather than `.brand-header button:focus`/`.brand-header
   a:focus` broadly — that would also catch `#brand-locale-save` and the
   language/currency `<select>`s inside `.brand-locale-menu`. */
.brand-mark:focus,
.brand-qr:focus,
.brand-icon-link:focus,
#brand-locale-toggle:focus,
.brand-subnav-bar a:focus {
  outline: 2px solid var(--crest-red-dark);
  outline-offset: 2px;
}

.brand-icon-wrap {
  position: relative;
  display: inline-flex;
}

.brand-icon-label {
  font-size: 0.75rem;
  letter-spacing: 0.02em;
}

.brand-badge {
  position: absolute;
  top: -0.5rem;
  right: -0.6rem;
  background: var(--crest-red);
  color: var(--crest-cream);
  border-radius: 999px;
  min-width: 1.1rem;
  height: 1.1rem;
  font-size: 0.7rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.2rem;
}

/* Department sub-banner, sits directly under the header. Restyled
   2026-07-18 to match the header's light look (see .brand-header above) —
   a thin gold rule reads as a distinct strip without a heavy color block.
   Redesigned 2026-07-21 (see the long comment in brand_subnav.html for the
   two confirmed bugs this replaces) from "9 supergroups always visible in
   the row" to a single "Shop by Department" trigger + panel, at every
   width -- `position: relative` anchors the panel below via `top: 100%`. */
.brand-subnav {
  /* style.css has a generic `nav, p:has(> a) { display: inline-flex }`
     rule (sized for its own small breadcrumb-pill pattern elsewhere) that
     otherwise wins here on cascade: `nav` is a valid, lower-specificity
     match, but nothing in this rule used to override its `display` once
     the flex layout below moved onto .brand-subnav-bar instead of living
     directly on .brand-subnav. inline-flex shrinks to content width
     instead of filling the header -- confirmed live, .brand-subnav
     measured ~393px on a 1024px viewport instead of ~1009px. */
  display: block;
  background: var(--crest-cream);
  border-bottom: 1px solid var(--crest-gold-border);
  padding: 0.4rem 1.5rem;
  position: relative;
}

/* Left-aligned rather than centered, and pulled in tighter (smaller type,
   smaller gap) -- previously centered at full 0.78rem/2rem gap, which read
   as a second, competing focal point under the header instead of a
   secondary utility row. */
.brand-subnav-bar {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 1.1rem;
}

.brand-subnav-all,
.brand-dept-trigger {
  color: var(--crest-ink);
  text-decoration: none;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  background: none;
  border: none;
  padding: 0.2rem 0;
  margin: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-family: inherit;
}

.brand-subnav-all:hover,
.brand-subnav-all[aria-current="true"],
.brand-dept-trigger:hover,
.brand-dept-trigger.is-open {
  color: var(--crest-red);
  /* style.css's generic `button:hover { background: var(--accent-hover) }`
     (0,1,1 specificity) otherwise beats this button's own plain
     `.brand-dept-trigger { background: none }` (0,1,0) on hover -- same
     bare-element cascade bug already found elsewhere in this file (see
     `.brand-subnav`'s comment above), just not caught here since it only
     shows up on `:hover`/`.is-open`, not on page load. Confirmed live: the
     trigger rendered as a solid dark-red block instead of the plain cream
     nav item it's meant to be. */
  background: none;
}

.brand-dept-trigger-arrow {
  transition: transform 0.15s var(--brand-ease, ease);
}

.brand-dept-trigger.is-open .brand-dept-trigger-arrow {
  transform: rotate(180deg);
}

/* Closed by default; static/brand-dept-menu.js toggles `.is-open` on
   click. Plain display:none/block -- no Foundation plugin owns this
   panel's state, so (unlike the old Drilldown setup) nothing measures its
   own size while hidden and bakes a wrong answer into an inline style. */
.brand-dept-panel {
  display: none;
  position: absolute;
  top: 100%;
  /* Flush with the far left edge (of `.brand-subnav`'s own box, which is
     this element's positioning ancestor) rather than centered/inset, and
     sized to its content (`width: fit-content`) instead of stretched to a
     fixed max-width -- the grid below sizes its own columns to
     `max-content`, so the panel ends up exactly as wide as the longest
     department name needs and no wider. Reset to `width: auto` in the
     small-width media query below, since `position: static` there means
     this element is meant to fill the mobile accordion's full width, not
     hug its content. */
  left: 0;
  width: fit-content;
  z-index: 40;
  background: #fff;
  border-bottom: 1px solid var(--crest-gold-border);
  box-shadow: 0 12px 24px -12px rgba(26, 16, 10, 0.25);
  padding: 1.75rem;
}

.brand-dept-panel.is-open {
  display: block;
}

/* 9 supergroups fit a 3x3 grid exactly -- revisit if SUPERGROUPS (nav.rs)
   grows past 9 and this stops dividing evenly. `max-content` columns (not
   `1fr`) so each column is only as wide as its longest department name --
   `.brand-dept-panel`'s `width: fit-content` then hugs the grid's own
   resulting width instead of stretching it back out. */
.brand-dept-grid {
  display: grid;
  grid-template-columns: repeat(3, max-content);
  gap: 1.5rem 2rem;
}

.brand-dept-col-heading {
  margin: 0 0 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--crest-red-dark);
  border-bottom: 1px solid var(--crest-gold);
  padding-bottom: 0.4rem;
}

.brand-dept-col ul {
  margin: 0;
  list-style: none;
  padding: 0;
}

.brand-dept-col a {
  display: block;
  padding: 0.35rem 0;
  color: var(--crest-ink);
  text-decoration: none;
  font-size: 0.88rem;
}

/* Gold underline is the entire feedback treatment here -- deliberately no
   outline box. `.brand-subnav-bar a:focus` (above) used to also catch
   these (every link in the panel is a descendant of `.brand-subnav`),
   painting a thick dark-red box around the whole row on click; scoping
   that rule to `.brand-subnav-bar` fixed it, and `outline: none` here
   makes sure the browser's own default focus ring doesn't quietly bring
   the same boxy look back. text-decoration (not border-bottom) so this
   never adds/removes layout height on click. */
.brand-dept-col a:hover,
.brand-dept-col a:focus,
.brand-dept-col a[aria-current="true"] {
  color: var(--crest-red);
  text-decoration: underline;
  text-decoration-color: var(--crest-gold-border);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  /* Same fix as .shop-category-menu's persistent-underline rule: default
     `text-decoration-skip-ink: auto` breaks the line at word-spaces in
     multi-word department names (e.g. "Beauty & Cosmetics"). */
  text-decoration-skip-ink: none;
  outline: none;
}

/* Accordion (small widths) lives in the same panel as the grid above but
   stays hidden until the max-width: 640px block below swaps them. Same
   Foundation Accordion Menu component as shop_list.html's category
   sidebar (.shop-category-menu) -- proven not to hit the Drilldown
   width-measurement bug this whole redesign is working around. */
.brand-dept-accordion {
  display: none;
  margin: 0;
}

.brand-dept-accordion > li > a {
  display: block;
  padding-right: 2rem;
  color: var(--crest-ink);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

/* Foundation's own default arrow (`.is-accordion-submenu-parent > a::after`
   in foundation.css) flips 180deg with no transition of its own -- an
   instant snap happening at the same moment jQuery's ~250ms slideDown/Up
   eases the row open, which is what read as a jarring "bounce" alongside
   the smooth height change. Matching the timing here (not literally
   removing anything from Foundation) is what actually fixes it. */
.brand-dept-accordion .is-accordion-submenu-parent > a::after {
  transition: transform 0.2s var(--brand-ease, ease);
}

.brand-dept-accordion .nested a {
  color: var(--crest-ink);
  font-size: 0.88rem;
  letter-spacing: normal;
  text-transform: none;
  padding: 0.45rem 0 0.45rem 1rem;
}

/* Same gold-underline-only treatment as `.brand-dept-col a` above -- no
   outline box, and `outline: none` blocks the browser's default focus
   ring from bringing the boxy look back on tap. */
.brand-dept-accordion a:hover,
.brand-dept-accordion a:focus,
.brand-dept-accordion a[aria-current="true"] {
  color: var(--crest-red);
  text-decoration: underline;
  text-decoration-color: var(--crest-gold-border);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  text-decoration-skip-ink: none;
  outline: none;
}

.brand-home {
  padding: 0 1.25rem 3rem;
}

.brand-hero {
  max-width: 72rem;
  margin: 2rem auto 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1.3fr 0.9fr;
  gap: 1.25rem;
  align-items: stretch;
}

/* Flattened 2026-07-18 (was a translucent, rounded, drop-shadowed card —
   the "soft UI" look the rest of the header/button redesign moved away
   from). No card container at all: there's no hero photo behind this text
   yet, and a bordered/backed box only reads as intentional when it's
   sitting on top of an image — against the plain cream page background it
   just looked like an arbitrary rounded box. Revisit with a real border+
   background (matching .product-card's flat convention) if a hero photo
   is added later. */
.brand-hero-copy {
  padding: 0;
  text-align: left;
}

.brand-eyebrow {
  margin: 0 0 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--crest-red-dark);
}

.brand-hero h1 {
  font-size: 2.6rem;
  margin: 0 0 0.5rem;
  color: var(--crest-red);
  line-height: 1.05;
}

.brand-rule {
  width: 6rem;
  height: 2px;
  background: var(--crest-gold);
  margin: 1rem 0;
}

.brand-tagline {
  font-style: italic;
  font-size: 1.15rem;
  color: var(--crest-red-dark);
  margin-bottom: 1.2rem;
}

.brand-blurb {
  font-size: 1.02rem;
  line-height: 1.8;
  margin: 0 0 1.6rem;
  max-width: 38rem;
}

.brand-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}

.brand-hero-panel {
  display: flex;
  align-items: stretch;
}

/* Flattened 2026-07-18 to the same flat-card convention already used by
   .product-card/.shop-sidebar (solid background, 1px gold border,
   border-radius: 2px, no shadow) instead of the old gradient/rounded/
   drop-shadowed "soft UI" card, which clashed with the rest of the
   redesign. Border switched from --crest-gold to --crest-gold-border
   (2026-07-21 consistency pass) -- this card's border is a real UI
   boundary, not a decorative rule, so it needs the darker AA-compliant
   token per the --crest-gold-border definition above; --product-card and
   the dept-* cards elsewhere already used the darker token, this was the
   one card border on the page that hadn't been updated to match. */
.brand-panel-card {
  width: 100%;
  background: #fff;
  color: var(--crest-ink);
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
  padding: 1.5rem;
}

/* Was crest-gold-light, tuned for legibility on the old dark-red gradient.
   Needs a color with real contrast now that the card is white — reuse
   crest-red-dark, the same "accent label" color already used by
   .brand-eyebrow and .shop-sidebar h2 elsewhere. */
.brand-panel-label {
  margin: 0 0 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.72rem;
  color: var(--crest-red-dark);
}

.brand-panel-card h2 {
  margin: 0 0 0.75rem;
  font-size: 1.35rem;
  color: var(--crest-ink);
}

.brand-panel-list {
  margin: 0;
  padding-left: 1rem;
  display: grid;
  gap: 0.55rem;
  line-height: 1.6;
}

/* Centered small-caps section-heading convention (Hancocks Signet Rings
   reference, planning/branding.md) — a thin gold rule centered under the
   heading text, matching the same divider treatment already used by
   .brand-rule in the hero. This is the first promo/story section on the
   page with its own visible heading (it previously only had an aria-label,
   with no heading text a sighted visitor could see), so it also improves
   that section's accessibility, not just its look. */
.brand-section-heading {
  max-width: 72rem;
  margin: 2rem auto 0;
  padding: 0 1.25rem;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--crest-ink);
}

.brand-section-heading::after {
  content: "";
  display: block;
  width: 3rem;
  height: 1px;
  background: var(--crest-gold);
  margin: 0.6rem auto 0;
}

.brand-highlights {
  max-width: 72rem;
  margin: 1.25rem auto 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

/* Border uses --crest-gold-border, not --crest-gold, for the same reason
   as .brand-panel-card above -- a real card boundary needs the ~3:1+
   AA-compliant token, not the ~2.2-2.4:1 accent-only gold. */
.brand-highlight-card {
  background: #fff;
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
  padding: 1.2rem;
}

.brand-highlight-card h3 {
  margin: 0 0 0.4rem;
  color: var(--crest-red-dark);
}

.brand-highlight-card p {
  margin: 0;
  line-height: 1.6;
}

@media (max-width: 900px) {
  .brand-hero {
    grid-template-columns: 1fr;
  }

  .brand-highlights {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .brand-home {
    padding: 0 0.9rem 2.5rem;
  }

  .brand-hero-copy {
    padding: 1.35rem;
  }

  .brand-hero h1 {
    font-size: 2.1rem;
  }

  .brand-cta {
    width: 100%;
  }

  /* The QR code exists so a *desktop* visitor can scan it with their own
     phone (see the note on .brand-qr) -- showing it to someone already
     browsing on that phone serves no purpose, and its ~150px block was the
     single biggest contributor to the header overflowing a 390px viewport
     (confirmed live: header content was clipping past the right edge on
     phone width). Dropping it here both fixes the overflow and removes a
     control with no function on the device it's rendered on. */
  .brand-qr {
    display: none;
  }

  /* Icon-only on phone width -- "Cart" / "Sign In" text labels next to
     already-recognizable icons were the remaining width past what
     .brand-icons had left to give after the search field, and duplicate
     information the icon (plus badge count, for cart) already carries. */
  .brand-icon-label {
    display: none;
  }

  .brand-icons {
    gap: 1rem;
  }

  .brand-subnav {
    padding: 0.5rem 1rem;
  }

  /* The panel already starts collapsed (.brand-dept-panel above) and is
     positioned by the trigger, not the viewport -- on phone width it just
     needs to sit in normal flow under the bar instead of floating over the
     page, and swap which of its two children (grid/accordion) is shown. */
  .brand-dept-panel {
    position: static;
    /* The desktop rule's `width: fit-content` would otherwise carry over
       and shrink this to its content width too -- here it needs to fill
       the mobile accordion's full row width instead. */
    width: auto;
    box-shadow: none;
    padding: 0.5rem 0 0;
  }

  .brand-dept-grid {
    display: none;
  }

  .brand-dept-accordion {
    display: block;
  }
}

/* Sign-in/register page: a narrow centered column with a large seal
   placeholder above the form, standing in for a real logo image (see the
   `.brand-seal` note in `brand_header.html`) until real artwork exists. */
.brand-auth {
  max-width: 26rem;
  margin: 3rem auto;
  padding: 0 1.5rem 3rem;
  text-align: center;
}

.brand-auth h1 {
  color: var(--crest-red);
  margin: 0 0 1.25rem;
}

.brand-auth form {
  text-align: left;
}

/* Auth-page links ("Forgot your password?", "Create an account", "Back to
   sign in", etc.) previously fell through to two unwanted defaults:
   style.css's bare `a { color: var(--accent) }` — a hardcoded legacy red
   never tied to the --crest-* palette — and, for the ones sitting alone in
   a `<p><a>...</a></p>`, style.css's generic `nav, p:has(> a) {
   display: inline-flex; background: var(--panel); border: 1px solid
   var(--border); ... }` rule. That rule exists for an unrelated
   breadcrumb-pill pattern elsewhere (see redesign-agent-logs/
   phase1-nav-orchestrator.md for the same class of cascade bug already
   found on `.brand-subnav`) — nothing here previously set a competing
   `display`/`background` for a plain auth-page paragraph, so it silently
   rendered as a bordered gray toolbar box instead of a plain centered line
   of text. Scoped to `.brand-auth` only. */
.brand-auth a {
  color: var(--crest-red-dark);
}

.brand-auth p:has(> a) {
  display: block;
  background: none;
  border: none;
  padding: 0;
  margin: 1rem 0 0;
  font-size: 0.9rem;
}

.brand-seal-lg {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 5rem;
  height: 5rem;
  margin: 0 auto 1.5rem;
  border-radius: 50%;
  background: var(--crest-red-dark);
  border: 3px solid var(--crest-gold);
  box-shadow: 0 0 0 2px var(--crest-cream) inset;
  color: var(--crest-gold-light);
  font-weight: 700;
  font-size: 1.6rem;
  text-decoration: none;
}

/* Product detail page: image gallery on the left, name/price/add-to-cart
   on the right — same two-column instinct as the shop list's
   sidebar+grid, just flipped to a 1:1 split since there's only one
   product's worth of content instead of a whole catalog.
   2026-07 redesign: the page is wrapped in `.product-detail-shell` (see
   shop_detail.html) rather than left to `.grid-container`'s full-bleed
   width — a single product's photo + copy reads as considered editorial
   layout at ~76rem with real margins, not as a stretched, sparse two-box
   row spanning the entire 1400px+ desktop viewport (confirmed live: at
   full bleed the gallery and text sat far apart with a dead gutter and
   the page trailed off in blank space below, which is exactly the "looks
   horrible" complaint this redesign exists to fix). */
.product-detail-shell {
  max-width: 76rem;
  margin: 0 auto;
  padding: 1.75rem 1.5rem 3rem;
}

.product-detail-back a {
  color: var(--crest-red-dark);
  text-decoration: none;
  font-size: 0.9rem;
}

.product-detail-back a:hover {
  text-decoration: underline;
}

.product-detail-layout {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
  flex-wrap: wrap;
}

/* `max-width: 28rem` here used to silently cap this column at 448px even
   when its Foundation grid cell (`.cell.medium-6` in shop_detail.html) had
   far more room to give it — confirmed live via computed bounding boxes:
   the cell measured ~650-700px wide on a normal desktop viewport while
   this rule held the actual gallery to 448px, leaving a dead gutter next
   to it. Dropped so the gallery genuinely fills its column; `width: 100%`
   plus `flex-wrap` on the row below is what keeps the thumbnail rail +
   main image proportioned inside whatever width that ends up being. */
.product-detail-gallery {
  width: 100%;
  display: flex;
  gap: 0.75rem;
}

.product-detail-gallery .product-card-noimg {
  width: 100%;
  aspect-ratio: 4 / 5;
  height: auto;
  border: 1px solid var(--crest-gold);
  border-radius: var(--brand-radius);
  background: #fff;
}

/* Vertical thumbnail rail — hovering/focusing/clicking a thumbnail swaps
   the large image in `.product-gallery-main` (see `product-gallery.js`).
   The up/down buttons around it scroll it by one thumbnail at a time;
   `.product-gallery-thumbs` itself stays scrollable too (mouse wheel,
   touch) as a fallback. */
/* `position: relative` so the scroll buttons below can float over this
   box (`position: absolute`) instead of sitting in the flex column as
   siblings of `.product-gallery-thumbs` — that's what keeps the rail's
   top (and so the first thumbnail) flush with `.product-gallery-main`'s
   top regardless of whether the up button happens to be shown or hidden.
   Explicit width matches the thumbnail width exactly, since this is no
   longer a flex container centering its child — just one block child
   (the rail) plus two floating buttons. */
.product-gallery-thumbs-wrap {
  position: relative;
  width: 3.5rem;
  flex-shrink: 0;
}

/* Exactly 7 thumbnails tall (7 * 3.5rem + 6 gaps of 0.5rem) before it
   scrolls — caps the rail's height instead of letting it grow with the
   product's photo count. */
/* Scrollbar hidden — the up/down buttons (`#product-gallery-scroll-up/
   -down`) are the intended way to move through the thumbnails, and the
   native scrollbar next to them just looked like clutter. Still scrolls
   via mouse wheel/touch/the buttons; only the visible bar is gone. */
.product-gallery-thumbs {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 27.5rem;
  overflow-y: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.product-gallery-thumbs::-webkit-scrollbar {
  display: none;
}

/* Floats just outside the rail (`top`/`bottom` set per-button below)
   rather than sitting inline above/below it — that's what keeps the
   rail's own top flush with `.product-gallery-main`'s top. */
.product-gallery-scroll {
  position: absolute;
  left: 0;
  width: 3.5rem;
  height: 1.1rem;
  padding: 0;
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
  background: var(--crest-cream, #fff);
  color: var(--crest-red-dark);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

#product-gallery-scroll-up {
  top: -1.45rem;
}

#product-gallery-scroll-down {
  bottom: -1.45rem;
}

.product-gallery-scroll:hover {
  background: var(--crest-gold-light);
}

/* Hidden via JS (`product-gallery.js`) rather than CSS alone — whether a
   scroll button is needed depends on whether the rail actually overflows
   and how far it's currently scrolled, which only JS knows. */
.product-gallery-scroll[hidden] {
  display: none;
}

.product-gallery-thumb {
  width: 3.5rem;
  height: 3.5rem;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
  background: #fff;
  cursor: pointer;
}

.product-gallery-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.product-gallery-thumb:hover,
.product-gallery-thumb.active {
  border-color: var(--crest-red);
  box-shadow: 0 0 0 1px var(--crest-red);
}

.product-gallery-main {
  flex: 1;
  min-width: 0;
}

/* `cover` instead of `contain` — `contain` shrinks the image to fit
   inside the box without cropping, which left empty side margins on any
   image narrower than the box's aspect ratio. `cover` always fills the
   full width (cropping top/bottom as needed instead).
   Height switched from a fixed `20rem` to `aspect-ratio: 4/5` (a standard
   product-photography portrait ratio) so the image scales with the
   column's actual width instead of staying a fixed 320px tall regardless
   of how much horizontal room `.product-detail-gallery` fixing its
   max-width bug (above) now gives it — at the old fixed height the photo
   read as a small square floating in the middle of a much wider column. */
.product-gallery-main img {
  width: 100%;
  aspect-ratio: 4 / 5;
  height: auto;
  object-fit: cover;
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  background: #fff;
  cursor: zoom-in;
  box-shadow: 0 8px 24px -12px rgba(var(--leather-shadow), 0.35);
}

/* Full-size zoom overlay opened by clicking the main image. `display: none`
   here (rather than relying on the `hidden` attribute alone) is needed
   because author CSS always wins over the UA stylesheet's own `[hidden]`
   rule — `:not([hidden])` is what actually re-shows it once JS clears the
   attribute. */
.product-zoom-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  cursor: zoom-out;
}

.product-zoom-overlay:not([hidden]) {
  display: flex;
}

.product-zoom-overlay img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border: 2px solid var(--crest-gold);
  background: #fff;
}

.product-detail-info {
  flex: 1 1 18rem;
  padding-top: 0.25rem;
}

.product-detail-eyebrow {
  margin: 0 0 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--leather-tan);
}

.product-detail-info h1 {
  color: var(--crest-ink);
  font-size: 2rem;
  line-height: 1.15;
  margin: 0 0 0.6rem;
}

.product-detail-price {
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--crest-red);
  margin: 0 0 1.1rem;
}

.product-detail-short {
  margin-bottom: 1.5rem;
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--crest-ink);
}

/* Buy box: groups price/short description/add-to-cart into one visually
   weighted panel (a thin gold-bordered card, matching `.product-card`'s
   convention) instead of letting them float as loose text next to the
   photo — gives the purchase decision a clear visual anchor, the same way
   Foundation's grid changes above gave the page real width to anchor it
   in. */
.product-detail-buybox {
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  background: #fff;
  padding: 1.5rem 1.75rem;
  margin-bottom: 1.75rem;
}

/* Reset for the same reason as `.brand-search`/`.product-card form` —
   style.css's generic `form` rule would otherwise wrap this in an
   unwanted gray panel. */
.product-detail-add {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 0.85rem;
}

.product-detail-add label {
  display: block;
  margin-bottom: 0.35rem;
}

.product-detail-add input[type="number"] {
  width: 4.5rem;
}

.product-detail-long {
  border-top: 1px solid var(--crest-gold);
  padding-top: 1.25rem;
}

.product-detail-long h2 {
  color: var(--crest-red-dark);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.85rem;
  font-weight: 700;
  margin: 0 0 0.75rem;
  border-top: none;
  padding-top: 0;
}

.product-detail-long p {
  line-height: 1.75;
}

/* Readable article width for the legal/careers pages — narrower than the
   shop layout since this is prose, not a grid. */
.brand-legal {
  max-width: 42rem;
  margin: 2rem auto;
  padding: 0 1.5rem 2rem;
  line-height: 1.7;
}

.brand-legal h1 {
  color: var(--crest-red);
  font-size: 1.8rem;
  /* --crest-gold-border, not --crest-gold, per planning/accessibility.md --
     --crest-gold alone is only ~2.2-2.4:1 against the cream background,
     under WCAG 1.4.11's 3:1 minimum for a UI-boundary rule like this. */
  border-bottom: 1px solid var(--crest-gold-border);
  padding-bottom: 0.5rem;
}

/* Terms of Service and Careers titles are centered (the rest of the legal
   pages keep the left-aligned heading) — opted in per-page via this class
   rather than changing `.brand-legal h1` for every page. */
.brand-legal h1.brand-banner-center {
  text-align: center;
}

.brand-legal h2 {
  color: var(--crest-red-dark);
  font-size: 1.1rem;
  margin-top: 1.75rem;
}

.brand-legal a {
  color: var(--crest-red);
}

/* style.css has a generic `nav, p:has(> a) { display: inline-flex; ... }`
   rule written for the small "<p><a>Prev</a> &middot; <a>Next</a></p>"
   toolbar under a page h1 (see its comment there). It also matches any
   ordinary prose <p> that happens to contain a link as a *direct* child --
   which is nearly every paragraph across the informational/legal pages
   this class is used on (mailto: links, "see our X policy" cross-links,
   etc.). Left unset, a plain sentence like "Contact us at <a>email</a>
   with your order number..." silently renders as a boxed inline-flex
   toolbar (background panel, border, padding, bold non-underlined link)
   instead of normal paragraph text -- confirmed by reading the two rules'
   computed specificity, both (0,1,1)/(0,1,2), so without an explicit
   override here it's a coin flip decided by stylesheet load order, not a
   deliberate style. `.brand-page` is prefixed on both rules below purely
   for extra specificity margin so this never again depends on load order,
   the same defensive habit as this file's other `nav`-collision fixes
   (`.brand-subnav`, `.dept-subcats`). */
.brand-page .brand-legal p {
  display: block;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0 0 1rem;
}

.brand-page .brand-legal p a {
  text-decoration: underline;
  font-weight: inherit;
}

/* Outlined uppercase button — the reference site's one consistent CTA
   style (its "SHOP NOW"/"EXPLORE"/"READ MORE"/"BOOK AN APPOINTMENT"
   buttons are all identically treated, no filled/primary variant), so the
   old red-filled `.brand-cta-primary` vs. gold-outlined `.brand-cta-
   secondary` distinction was dropped rather than reconciled with it.
   Shared by the hero's <a> CTA and the product grid's <button> "Add to
   cart" — buttons don't inherit font/cursor by default the way anchors do,
   so those are set explicitly here to keep both looking identical. */
.brand-cta {
  display: inline-block;
  padding: 0.75rem 2rem;
  background: transparent;
  color: var(--crest-ink);
  border: 1px solid var(--crest-ink);
  border-radius: 0;
  text-decoration: none;
  font-family: inherit;
  font-size: 0.85rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
  cursor: pointer;
}

.brand-cta:hover {
  background: var(--crest-ink);
  color: var(--crest-cream);
}

.brand-cta-small {
  padding: 0.4rem 0.9rem;
  font-size: 0.7rem;
  width: 100%;
}

/* Product detail page's "Add to cart" — same outlined treatment as every
   other `.brand-cta`, just narrower padding to fit next to the quantity
   input. */
.brand-cta-pill {
  padding: 0.55rem 1.75rem;
}

/* Two-column shop layout: a fixed-width category sidebar (the structural
   piece borrowed from the Amazon reference in design-references/) plus a
   flexible product grid. Overrides style.css's plain `main { max-width:
   760px; margin: 0 auto }` rule, which would otherwise fight the sidebar
   for space and center-margin itself oddly as a flex child.
   No `max-width`/auto-centering — runs the full page width and sits close
   to the header (small top margin, small side padding) to maximize the
   space available to the sidebar and product grid rather than leaving
   unused margin on either side. */
/* The comment above describes a `.shop-layout` class that predates the
   current markup -- shop_list.html was refactored to Foundation's grid-x/
   cell system (`<main id="main" class="cell small-12 medium-9">`) but
   nothing was ever added to override style.css's plain `main { max-width:
   760px }` for THIS main element specifically, so it silently won anyway:
   confirmed via direct measurement at a 3840px viewport that `#main` was
   still clamped to 760px wide regardless of the sidebar/grid-container
   width fixes, squeezing however many product-grid columns the viewport
   earned into a 760px-wide strip. department_detail.html's `<main>` has
   the exact same problem despite having no `.cell` class at all (it isn't
   inside a grid-x there) -- confirmed live, same symptom.
   `:has(.product-grid)` targets exactly the storefront pages that
   actually need full width (shop listing, department pages) without
   touching genuinely text-only pages like FAQ/legal/contact, which stay
   at the narrower, more readable 760px on purpose. */
.brand-page main:has(.product-grid) {
  max-width: none;
}

.shop-layout {
  display: flex;
  align-items: flex-start;
  gap: 1.25rem;
  margin: 0.6rem 0 0;
  padding: 0 0.75rem;
}

/* `width: fit-content` instead of a fixed flex-basis — the box shrinks to
   fit its longest link ("Electronics & accessories") plus a small buffer,
   rather than reserving a fixed width that leaves empty space on the right
   for every shorter category name. */
.shop-sidebar {
  flex: 0 0 auto;
  width: fit-content;
  min-width: 7rem;
  background: var(--crest-cream, #fff);
  border: 1px solid var(--crest-gold-border);
  border-radius: 2px;
  padding: 0.65rem 1.1rem 0.65rem 0.85rem;
}

.shop-sidebar h2 {
  margin: 0 0 0.4rem;
  font-size: 0.9rem;
  color: var(--crest-red);
  border-bottom: 1px solid var(--crest-gold);
  padding-bottom: 0.3rem;
}

.shop-sidebar ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.shop-sidebar li {
  margin: 0.3rem 0;
}

.shop-sidebar a {
  color: var(--crest-ink);
  text-decoration: none;
  font-size: 0.92rem;
  white-space: nowrap;
}

/* No `font-weight` change here on purpose — bolding a hovered link makes
   it wider, and since the box itself is sized with `width: fit-content`,
   that would resize/expand the whole sidebar box every time a different
   link is hovered. Color + underline communicate the same thing without
   changing any text's width. */
.shop-sidebar a:hover,
.shop-sidebar a[aria-current="true"] {
  color: var(--crest-red);
  text-decoration: underline;
}

.shop-breadcrumb {
  font-size: 0.82rem;
  color: var(--crest-red-dark);
  margin: 1rem 0 0.5rem;
}

.shop-breadcrumb a {
  color: var(--crest-red-dark);
}

.shop-breadcrumb [aria-current="page"] {
  color: var(--crest-ink);
}

/* Foundation's Accordion Menu (data-accordion-menu) for the shop
   sidebar's department list -- 26 departments each listing several
   subcategories would be several hundred lines tall shown flat; the
   accordion keeps only the relevant department's subcategories visible at
   once. Restyled to match the flat/minimal look rather than Foundation's
   default (chevron icons, generic borders). */
.shop-category-menu,
.shop-category-menu .nested {
  list-style: none;
  margin: 0;
  padding: 0;
}

.shop-category-menu > li {
  border-bottom: 1px solid var(--crest-gold-border);
}

/* No padding-right for a chevron -- there isn't one (see the `::after`
   suppression below). This accordion used to set `data-submenu-toggle=
   "true"` (shop_list.html), which rendered a separate real `<button>` and
   left the department name's own `<a>` as a plain navigation link --
   meaning a tap on the name text navigated straight to that category
   instead of opening its subcategory list, and only the small separate
   button actually toggled it. Removed that option so the whole row (name
   included) is one unified click target that opens/closes the accordion,
   matching the already-working mobile department mega-menu
   (`.brand-dept-accordion`, brand-dept-menu.js), which never used a
   separate toggle button or a visible arrow either. `white-space: nowrap`
   is what lets the sidebar's `fit-content` width (shop.css) measure each
   row's true unwrapped width instead of a wrapped, artificially-narrower
   one. */
.shop-category-menu > li > a {
  color: var(--crest-ink);
  font-size: 0.92rem;
  padding: 0.5rem 0;
  white-space: nowrap;
}

/* Foundation's own default chevron (foundation.css:
   `.accordion-menu .is-accordion-submenu-parent:not(.has-submenu-toggle)
   >a::after`) is what used to visually mark "this expands" now that
   there's no separate toggle button -- but with the department name
   itself as the single, full-row click target, a dedicated arrow icon is
   no longer needed to hint at a smaller tap zone. Suppressed here rather
   than in foundation.css since this is the built output of
   foundation-input.scss, not hand-edited directly.
   A first pass at this used a plain `.shop-category-menu .is-accordion-
   submenu-parent > a::after` selector, which computed to `display: block`
   in the browser regardless -- confirmed live via `getComputedStyle(a,
   '::after')`, not just a screenshot glance. Cause: Foundation's own
   selector includes `:not(.has-submenu-toggle)`, which still counts as a
   class in specificity math (0,3,2) and beat the plain version above
   (0,2,2), even though brand.css loads after foundation.css -- specificity
   is compared before source order. Matching Foundation's selector exactly
   (including the `:not()`) plus `!important` here as a deliberate belt-
   and-suspenders choice: this suppresses a vendored, built-from-SCSS rule
   we don't hand-edit directly, not fighting our own architecture, so
   `!important` is the pragmatic call rather than a specificity math risk
   a future Foundation rebuild could quietly re-break. */
.shop-category-menu .is-accordion-submenu-parent:not(.has-submenu-toggle) > a::after {
  display: none !important;
}

.shop-category-menu > li > a:hover,
.shop-category-menu > li > a[aria-current="true"] {
  color: var(--crest-red);
}

/* Browser-default focus ring (shows on every click/tap once the link
   receives focus, not just keyboard navigation -- confirmed as what Al
   was seeing) suppressed on plain `:focus`, then reinstated on
   `:focus-visible` -- which the browser only matches for keyboard/
   non-pointer focus -- so Tab-navigating still shows a clear indicator. */
.shop-category-menu > li > a:focus {
  outline: none;
}

.shop-category-menu > li > a:focus-visible {
  outline: 2px solid var(--crest-red-dark);
  outline-offset: 2px;
}

/* Persistent "this department is expanded" indicator -- independent of
   hover/focus, which are transient. Foundation's AccordionMenu toggles
   `is-active` on the nested submenu `<ul>` itself (`down()`/`up()` in
   foundation.accordionMenu.js), never on the `<li>` -- confirmed live by
   toggling and inspecting classList before/after -- so `:has()` is what
   lets this reach the department name (`<a>`), a sibling of that `<ul>`,
   from the open/closed state actually living one level down. */
.shop-category-menu > li:has(> ul.nested.is-active) > a {
  text-decoration: underline;
  text-decoration-color: var(--crest-gold-border);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
  /* Without this, Chrome's default `text-decoration-skip-ink: auto` broke
     the line at the word-space in multi-word names (e.g. "Baby Gear") --
     confirmed live via a zoomed screenshot, a real visible gap, not a
     rendering artifact of the screenshot itself. `skip-ink` is meant to
     duck under glyph descenders, not fragment at spaces, but that's the
     behavior Chrome produces here with a custom thickness/offset. `none`
     forces one continuous stroke regardless of word count. */
  text-decoration-skip-ink: none;
}

.shop-category-menu .nested {
  margin: 0 0 0.5rem 0.75rem;
}

.shop-category-menu .nested a {
  color: var(--crest-ink);
  font-size: 0.85rem;
  padding: 0.3rem 0;
  white-space: nowrap;
}

.shop-category-menu .nested a:hover,
.shop-category-menu .nested a[aria-current="true"] {
  color: var(--crest-red);
  text-decoration: underline;
}

.shop-category-menu .nested a:focus {
  outline: none;
}

.shop-category-menu .nested a:focus-visible {
  outline: 2px solid var(--crest-red-dark);
  outline-offset: 2px;
}

.shop-main {
  flex: 1;
  max-width: none;
  margin: 0;
  padding: 0;
}

/* Category sidebar as an actual panel — the shop_list.html markup
   (`<aside class="cell small-12 medium-3 shop-category-aside">`) never had
   its own card treatment; it inherited nothing but the plain page
   background, so "Category" + a bare bullet list sat directly on the cream
   page with no visual weight of its own next to the bordered product grid
   beside it. Matches `.product-card`'s flat-card convention (white fill,
   thin gold border, shared radius) so the two columns read as one
   considered layout. */
.shop-category-aside {
  background: #fff;
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  /* Left/right in `ch` (not `rem`) on purpose -- breathing room around
     whichever department name ends up being the widest only makes sense as
     a text-relative unit; a fixed rem value doesn't scale with that. Pairs
     with `.shop-category-aside`'s `width: fit-content` in shop.css.
     Asymmetric on a second pass: left pulled in to 1ch specifically so the
     department text itself sits further left inside the box, right eased
     down to 2ch (from a uniform 3ch each) to tighten the box's overall
     width a bit further still. */
  padding: 1.1rem 2ch 1.35rem 1ch;
  align-self: flex-start;
  position: sticky;
  top: 1rem;
}

/* Dense product grid (the other structural piece from the Amazon
   reference) — each card is its own bordered tile with image, name, price,
   and a quick "Add to cart" so a shopper doesn't have to open the detail
   page just to buy something they already recognize. Column layout comes
   from Foundation's grid-x/cell classes on the markup (small-6/medium-4/
   large-3 -- 2/3/4-up, each dividing evenly into the 12-column grid) so
   this rule only resets the <ul>/<li> defaults; it no longer sets its own
   CSS Grid columns. */
.product-grid {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Foundation's compiled build here only ships small/medium/large
   breakpoints -- `large-3` (4-up) is the widest column count it has, and
   it never changes again above ~1024px, so a normal 1400-1600px desktop
   window (not just an exotic 4K/ultrawide) sat at the same 4-up density as
   a 1024px laptop with real spare width going unused. Confirmed live on a
   3840px-wide (36" 4K) screen too: the grid stayed at 4 columns with well
   over half the screen sitting empty to the right. These add the missing
   wider steps directly (same `calc(X% - 1.875rem)` gutter math .large-3
   itself uses, for grid-margin-x's 0.9375rem-each-side compensation),
   starting at 1200px (5-up) rather than jumping straight from 4-up to 6-up
   at 1600px, so mainstream desktop widths get a real intermediate step. */
@media (min-width: 1200px) {
  .product-grid > .cell {
    width: calc(20% - 1.875rem); /* 5-up */
  }
}
@media (min-width: 1600px) {
  .product-grid > .cell {
    width: calc(16.6667% - 1.875rem); /* 6-up */
  }
}
@media (min-width: 2000px) {
  .product-grid > .cell {
    width: calc(12.5% - 1.875rem); /* 8-up */
  }
}
@media (min-width: 2600px) {
  .product-grid > .cell {
    width: calc(10% - 1.875rem); /* 10-up */
  }
}
@media (min-width: 3400px) {
  .product-grid > .cell {
    width: calc(8.3333% - 1.875rem); /* 12-up */
  }
}

.product-card {
  background: #fff;
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: transform 0.2s var(--brand-ease), box-shadow 0.2s var(--brand-ease), border-color 0.2s var(--brand-ease);
}

/* Subtle lift + shadow on hover, restrained rather than a "soft UI" glow —
   consistent with the rest of the redesign's flat-card convention, just
   with enough motion to signal the card is interactive. Skipped entirely
   for visitors who've asked the OS for reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .product-card:hover {
    transform: translateY(-3px);
    border-color: var(--crest-red);
    box-shadow: 0 10px 20px -12px rgba(var(--leather-shadow), 0.4);
  }
}

/* The quick "Add to cart" mini-form is just a button wrapper, not a real
   form panel — without this reset it would inherit style.css's generic
   `form` styling (background/padding/border/shadow) the same way the
   search bar did, nesting an unwanted gray-bordered box inside this
   already gold-bordered card. */
.product-card form {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  margin: 0;
}

.product-card-link {
  color: var(--crest-ink);
  text-decoration: none;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: center;
  flex: 1;
}

.product-card-link:hover .product-card-name {
  color: var(--crest-red);
}

.product-card img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--leather-tan-light);
  border-bottom: 1px solid var(--crest-gold-border);
}

.product-card-noimg {
  width: 100%;
  aspect-ratio: 1 / 1;
  background: var(--leather-tan-light);
  border: none;
  border-bottom: 1px dashed var(--crest-gold);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Restores the "No photo yet" label this class used to get from shop.css
   (removed there — see that file's header comment — since it was a plain
   non-aspect-ratio box that no longer matches this element's sizing). */
.product-card-noimg::after {
  content: "No photo yet";
  color: var(--crest-red-dark);
  font-size: 0.78rem;
  font-style: italic;
  opacity: 0.7;
}

.product-card-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.5em;
  padding: 0.85rem 0.85rem 0;
  font-size: 0.92rem;
  line-height: 1.3;
  text-decoration: none;
}

.product-card-price {
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--crest-red);
  margin: 0.6rem 0 0;
}

.product-card .card-section {
  padding: 0 0.85rem 0.85rem;
  margin-top: auto;
}

.product-card-oos {
  color: var(--muted, #57606a);
  font-size: 0.85rem;
  font-style: italic;
}

/* Department landing page (department_detail.html). One reusable layout
   for every department regardless of subcategory/product count -- see
   planning/category-taxonomy.md for the research this is based on
   (subcategory tiles shown above the product grid, not buried below
   promotional content; an honest empty state rather than a fake-populated
   page for a department with no stock yet). */
.dept-hero {
  max-width: 48rem;
  margin: 1.5rem 0 2rem;
}

.dept-hero h1 {
  color: var(--crest-ink);
  font-size: 2.1rem;
  margin: 0.3rem 0 0;
}

/* style.css's generic `nav, p:has(> a) { display: inline-flex }` rule
   (written for the footer's narrow legal-links nav) also matches any other
   bare <nav> element, including this one -- without the override below it
   shrinks this nav to its content width, which starves the CSS Grid child
   inside it of any real width to lay out columns against. */
.dept-subcats {
  display: block;
  margin: 0 0 2rem;
}

/* Same auto-fill/minmax technique as .product-grid -- 3 subcategories
   produce one short row, 9 produce three, no per-department special
   casing needed. */
.dept-subcat-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.75rem;
}

/* Below ~448px of usable width (a 390px phone minus `.grid-container`'s
   side padding) even one 11rem `auto-fill` column plus its neighbor's gap
   doesn't fit, so `auto-fill` collapses to a single column — 6-9
   subcategory tiles stacked full-width one per row, pushing the actual
   product grid far down the page. Forcing exactly 2 columns here instead
   keeps tiles tappable (each still gets ~45% of a 390px screen, well
   above any touch-target minimum) while roughly halving that scroll
   distance. */
@media (max-width: 28.6875em) {
  .dept-subcat-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.dept-subcat-tile {
  display: block;
  text-align: center;
  padding: 1rem 0.6rem;
  background: #fff;
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
  color: var(--crest-ink);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 600;
  transition: transform 0.2s var(--brand-ease), box-shadow 0.2s var(--brand-ease), border-color 0.2s var(--brand-ease);
}

.dept-subcat-tile:hover,
.dept-subcat-tile:focus {
  color: var(--crest-red);
  border-color: var(--crest-red);
}

@media (prefers-reduced-motion: no-preference) {
  .dept-subcat-tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 16px -10px rgba(var(--leather-shadow), 0.4);
  }
}

.dept-section-heading {
  color: var(--crest-ink);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--crest-gold-border);
  padding-bottom: 0.6rem;
  margin-bottom: 1.25rem;
}

.dept-empty-state {
  max-width: 34rem;
  padding: 2rem;
  background: #fff;
  border: 1px solid var(--crest-gold-border);
  border-radius: var(--brand-radius);
}

/* style.css's generic `nav, p:has(> a) { display: inline-flex; background;
   border; padding }` rule (written for a "<p><a>...</a></p>" byline
   pattern elsewhere -- same gotcha already fixed for `.shop-breadcrumb`/
   `.shop-my-orders` in shop.css and `.dept-subcats` above) also matches
   both paragraphs used inside this card ("We're currently curating..." and
   the "not found" card's own closing sentence), since each has an <a> as a
   direct child. Confirmed: without this reset those sentences render as a
   bordered gray pill nested inside the already gold-bordered card instead
   of plain body text. */
.dept-empty-state p {
  display: block;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0 0 0.75rem;
}

.dept-empty-state p:last-child {
  margin-bottom: 0;
}

/* Footer inherited from style.css's plain `footer` rule reads oddly against
   the cream/serif page above it, so the brand page restyles it to match.
   No `max-width` here (unlike `.brand-legal`) — the copyright line below is
   kept to one line, which needs the full page width to fit without
   wrapping. */
/* Back to a centered, capped-width footer (like the original) rather than
   full page width — just a bit wider than style.css's plain `footer {
   max-width: 760px }` default. Both properties need to be set explicitly
   here even though only `max-width` changed, since leaving `margin`
   unset would fall back to style.css's `margin: 2rem auto 0`, which is
   the same value anyway but shouldn't be left implicit by accident. */
.brand-page footer {
  max-width: 900px;
  margin: 2rem auto 0;
  border-top: 1px solid var(--crest-gold);
  color: var(--crest-red-dark);
  font-family: Garamond, Georgia, "Times New Roman", serif;
  text-align: center;
  padding: 0 1rem;
}

/* The legal-links nav is an inline-flex box (see style.css), so it needs
   its own `justify-content: center` in addition to the footer's
   `text-align: center` — text-align alone only centers it as a block,
   not the links inside it. */
.brand-page footer nav {
  justify-content: center;
}

.brand-page footer a {
  color: var(--crest-red);
}

/* Copyright/trademark notice is two deliberate lines (joined by `\n` in
   `copyright_notice` — see `FooterContent::default`). `pre-line` is what
   makes that `\n` actually render as a line break instead of collapsing
   into one line the way HTML whitespace normally does. */
.brand-page footer p {
  white-space: pre-line;
  font-size: 0.8rem;
}

/* ---------- Customer account pages (Settings / My Orders / Order detail) ----------
   2026-07-21 visual/UX consistency pass. Every selector below is gated by a
   class that only appears in account_settings.html, account_orders.html, and
   account_order_detail.html, so none of it can affect any other page's
   <form>/<p><a></p>/.badge markup even though the underlying bugs are shared
   site-wide -- deliberately not fixed via the bare selectors themselves,
   to stay isolated from other in-flight redesign work elsewhere.

   Bugs found and fixed here (confirmed by reading style.css, not guessing):
   1. style.css's bare `form { background; border; box-shadow; padding }`
      rule (written for the admin tool's plain gray panel forms) has no
      `.brand-page` override anywhere in this file, so the Settings form and
      the My Orders "Sign out" form were both rendering as a gray bordered
      admin-panel card -- directly contradicting the Hancocks reference's
      white/cream, unboxed editorial look. `.account-form` resets it.
   2. The same file's bare `nav, p:has(> a) { display: inline-flex; background;
      border; padding }` rule (written for the footer's legal-links row) also
      matches every "back to..." link paragraph on all three pages, turning a
      plain sentence into a stray gray pill box. `.account-back-link` /
      `.account-welcome` reset it, mirroring the already-established
      `.shop-breadcrumb`/`.shop-my-orders` fix in shop.css.
   3. Order-status badges (`<span class="badge" data-status="...">`) had no
      matching color rule at all -- style.css's `.badge[data-status=...]`
      selectors are all keyed to the *product/employee/vendor* workflow
      vocabulary (APPROVED/PENDING/DRAFT/REJECTED/...), not the *order*
      vocabulary actually used here (PENDING_PAYMENT/PAID/FULFILLED/
      CANCELLED -- confirmed in checkout.rs/orders_admin.rs), so every order
      status silently fell through to the neutral gray default. Colors below
      reuse the palette already established by `.callout.success`/
      `.callout.warning`/`.callout.alert` above, just re-keyed to order
      status values via `.account-status-badge` -- deliberately not a bare
      `.badge[data-status="PAID"]` rule, since that would also repaint
      checkout_success.html's and gift_card_success.html's badges, which are
      out of scope for this pass. */

.account-form {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  margin: 0 0 1.5rem;
}

.account-back-link,
.account-welcome {
  display: block;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0 0 1.25rem;
  font-size: 0.9rem;
}

.account-back-link a,
.account-welcome a {
  color: var(--crest-red-dark);
  text-decoration: none;
}

.account-back-link a:hover,
.account-back-link a:focus-visible,
.account-welcome a:hover,
.account-welcome a:focus-visible {
  text-decoration: underline;
}

/* `.brand-page` sets `overflow-x: hidden` at the body level (see the root
   rule near the top of this file); without a scrollable ancestor of its
   own, a table wider than the viewport -- the 6-column order-item table
   especially -- would be silently clipped on a narrow phone instead of
   reachable by scrolling. This wrapper gives it somewhere to scroll. */
.account-table-scroll {
  overflow-x: auto;
  margin: 0 0 1.5rem;
}

.account-table-scroll table.table {
  margin: 0;
}

.account-status-badge[data-status="PAID"] {
  background: #edf5e6;
  border-color: #9fc47c;
  color: #33511f;
}

.account-status-badge[data-status="FULFILLED"] {
  background: var(--crest-ink);
  border-color: var(--crest-ink);
  color: var(--crest-cream);
}

.account-status-badge[data-status="PENDING_PAYMENT"] {
  background: var(--leather-tan-light);
  border-color: var(--leather-tan);
  color: #6b3d13;
}

.account-status-badge[data-status="CANCELLED"] {
  background: #fbeceb;
  border-color: #d99b91;
  color: var(--crest-red-dark);
}

.account-order-summary {
  text-align: right;
  margin: 0 0 2rem;
  font-size: 0.95rem;
  line-height: 1.8;
}

.account-order-summary strong {
  font-size: 1.2rem;
  color: var(--crest-red-dark);
}

/* Settings page only: the "Show/Hide" password-reveal button (style.css)
   uses the admin tool's `--accent`/`--muted` variables on hover/focus,
   which don't belong to this page's crest palette. Scoped via a second
   class rather than overriding `.password-toggle` itself, so
   customer_login.html/customer_register.html's password toggles (out of
   scope for this pass) are untouched. */
.account-password-toggle:hover,
.account-password-toggle:focus-visible {
  color: var(--crest-red-dark);
}

/* Visibly distinguishes the read-only email field from the editable Name
   field above it -- without this, `.brand-page input[type="email"]`'s own
   `background: #fff` (needed so the *enabled* inputs look crisp/white)
   quietly cancels out most browsers' default disabled-input dimming. */
.account-field-disabled:disabled {
  background: var(--crest-cream);
  color: #6b5b4d;
  cursor: not-allowed;
}

/*
 * Copyright © 1996 - 2026 Gousse & Gousse Inc. or its Affiliates., All Rights Reserved.
 *  author: Al D. Gousse
 *    site: www.goussecorp.com
 *   email: info@goussecorp.com
 *  twitter: @goussecorp
 **/
