.elementor-kit-834{--e-global-color-primary:#262220;--e-global-color-secondary:#4A3B2A;--e-global-color-text:#262220;--e-global-color-accent:#8B2E1F;--e-global-color-8c442ed:#3D4F4C;--e-global-color-e2ba329:#F5A02F;--e-global-color-6f5ae59:#E2B79F;--e-global-color-20aae31:#B2571F;--e-global-typography-primary-font-family:"Oswald";--e-global-typography-secondary-font-family:"Oswald";--e-global-typography-text-font-family:"PT Sans";--e-global-typography-accent-font-family:"Oswald";--e-global-typography-accent-font-weight:600;font-family:"PT Sans", Sans-serif;}.elementor-kit-834 button,.elementor-kit-834 input[type="button"],.elementor-kit-834 input[type="submit"],.elementor-kit-834 .elementor-button{background-color:#8B2E1F;font-family:"Oswald", Sans-serif;font-weight:600;color:#ffffff;border-radius:4px 4px 4px 4px;padding:8px 32px 8px 32px;}.elementor-kit-834 e-page-transition{background-color:#FFBC7D;}.elementor-kit-834 a{color:#4A3B2A;}.elementor-kit-834 a:hover{color:#8B2E1F;}.elementor-kit-834 h1{font-family:"Oswald", Sans-serif;}.elementor-kit-834 h2{font-family:"Oswald", Sans-serif;}.elementor-kit-834 h3{font-family:"Oswald", Sans-serif;}.elementor-kit-834 h4{font-family:"Oswald", Sans-serif;}.elementor-kit-834 h5{font-family:"Oswald", Sans-serif;}.elementor-kit-834 h6{font-family:"Oswald", Sans-serif;}.elementor-section.elementor-section-boxed > .elementor-container{max-width:1140px;}.e-con{--container-max-width:1140px;}.elementor-widget:not(:last-child){--kit-widget-spacing:20px;}.elementor-element{--widgets-spacing:20px 20px;--widgets-spacing-row:20px;--widgets-spacing-column:20px;}{}h1.entry-title{display:var(--page-title-display);}.site-header .site-branding{flex-direction:column;align-items:stretch;}.site-header{padding-inline-end:0px;padding-inline-start:0px;}.site-footer .site-branding{flex-direction:column;align-items:stretch;}@media(max-width:1024px){.elementor-section.elementor-section-boxed > .elementor-container{max-width:1024px;}.e-con{--container-max-width:1024px;}}@media(max-width:767px){.elementor-section.elementor-section-boxed > .elementor-container{max-width:767px;}.e-con{--container-max-width:767px;}}/* Start custom CSS *//* --- orca:utilities:start --- */
@import url("https://fonts.googleapis.com/css2?family=Oswald:wght@400;700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=PT+Sans:wght@400;700&display=swap");
:root{--orca-font-head:"Oswald", Georgia, "Times New Roman", serif;--orca-font-body:"PT Sans", system-ui, -apple-system, "Segoe UI", sans-serif}
.orca-section{font-family:var(--orca-font-body)}
.orca-section h1,.orca-section h2{font-family:var(--orca-font-head)}

:root {
  --brand: #4A3B2A;        --accent: #8B2E1F;
  --chrome: #4A3B2A;
  --ground: #FAFAFB;      --recessed: #F1F0F1;
  --ink: #1A1A1A;            --ink-muted: #5C5C5C;
  --reversed: #FFFFFF;  --hairline: #E5E3E2;
  --dark: #1B1918;
  /* THE INK THAT SITS ON THE ACCENT, decided by contrast (WCAG luminance),
     published as a token so the PLUGIN's chrome - the mobile action bar first
     among it - paints accent surfaces without guessing ("solid accent with
     white/text, best contrast" - Nick, 30 Aug). */
  --on-accent: #ffffff;
  --band-tint: #F3F2F3;  --chrome-rgb: 74, 59, 42;
  /* Two shadows, and only two. Both are barely there: a shadow you can SEE is
     a shadow doing decoration rather than telling you a thing is lifted off
     the page. Cast in a brand-tinted near-black, never pure black. */
  --shadow-sm: 0 1px 2px rgba(25, 22, 19, .04), 0 2px 6px rgba(25, 22, 19, .05);
  --shadow-md: 0 2px 4px rgba(25, 22, 19, .05), 0 8px 22px rgba(25, 22, 19, .08);
  --pad: clamp(48px, 6.5vw, 72px);
  /* THE STORE RHYTHM (Nick, 9 Sep: "reduce padding/spacing in this design
     system", then "shrink padding between sections up to snug"). A
     storefront page is a stack of merchandising strips, and the reading
     rhythm above reads as dead air between them. Snug is the ceiling he
     named: each band carries it top and bottom, so two bands meet across
     one snug-and-snug seam. The assembler swaps a storefront band's
     var(--pad) for this; nothing else uses it. */
  --pad-store: var(--snug);
  --gutter: clamp(20px, 5vw, 48px);
  --radius: 8px;
  /* See .orca-site-header: a known height, not a derived one. */
  --header-h: 68px;  --header-h-compact: 52px;
  /* TWO grid widths. The content column is the narrower one, because its width
     is a reading decision. The chrome - top bar, header, footer - runs wider:
     it is the FRAME around the content, and a frame that sits inside the thing
     it frames looks accidental. Wider also puts the logo and the call to
     action nearer the page edges, which is where the eye goes looking for
     them. Both are still grids; neither is full-bleed. */
  --grid: 1200px;  --grid-wide: 1350px;
  --measure: 65ch;
  /* Relationship spacing. NOT one uniform gap - see SPACE in design-systems.orca-ts. */
  --tight: 8px;  --snug: 16px;
  --loose: 32px;  --block: 64px;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--ground); color: var(--ink);
  font: 17px/1.65 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* CLIP, NOT HIDDEN (invariant 1, and the 28 Aug audit). Hidden makes the
     element a scroll container, which silently breaks position: sticky on
     every header inside it - and the utility stylesheet already shipped
     clip on this same element, so the site carried both. */
  overflow-x: clip;
}

/* ---- type ------------------------------------------------------------- */
h1, h2, h3 {
  margin: 0; line-height: 1.12; font-weight: 700; letter-spacing: -0.015em;
  /* No orphan on the last line of a heading, and no ugly break in a two-word
     phrase. Falls back to normal wrapping where unsupported, so it costs
     nothing to have. */
  text-wrap: pretty;
}
/* NEVER text-wrap: balance, anywhere, in any system. It is pretty or it is
   nothing. Balancing re-flows the whole heading to even the line lengths, so
   the same words break differently at two widths a few pixels apart and a
   headline approved at one size is a different shape at another. Pretty only
   rescues the last line and leaves the rest alone, which is the part that was
   actually wrong. Checked by assertNoBalance, not trusted. */
/* Body copy too - same orphan problem, and cheaper than fixing widows by hand. */
p, li { text-wrap: pretty; }
/* The hero is off the interior scale on purpose: a restaurant wants a loud
   hero and quiet interior headings, and one ratio cannot do both. */
h1 { font-size: clamp(34px, 6.2vw, 56px); }
h2 { font-size: clamp(26px, 3.4vw, 41px); }
h3 { font-size: 23px; line-height: 1.25; }
p  { margin: 0; max-width: var(--measure); }
.orca-lead { font-size: 19px; color: var(--ink-muted); }
.orca-eyebrow {
  font-size: 13px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent);
}

/* ---- the grid --------------------------------------------------------- */
/* EVERY section puts its content in the same column, full-bleed ones
   included, so nothing drifts out of alignment as you scroll.

   THE BAND'S OWN PADDING SETTING WINS, THE RHYTHM IS THE FALLBACK. Every
   band writes its padding as an Elementor setting (the 12 Aug decision),
   and Elementor emits it as --padding-top/-right/-bottom/-left custom
   properties at element specificity - but the properties only matter if
   something consumes them, and Elementor's own consumer is an early
   .e-con rule this class rule silently outranked. So the featured band's
   flush seam, the carousel's tuck and the whole store rhythm sat in the
   page data and never reached the screen (surfaced 9 Sep, when "shrink
   padding to snug" visibly did nothing). One rule, both layers: consume
   the band's variables, fall back to the reading rhythm - which is also
   exactly what the plain-HTML previews get, where no variables exist. */
.orca-section {
  padding: var(--padding-top, var(--pad)) var(--padding-right, var(--gutter))
           var(--padding-bottom, var(--pad)) var(--padding-left, var(--gutter));
}
.orca-inner   { max-width: var(--grid); margin: 0 auto; width: 100%; }
.orca-inner.orca-wide { max-width: var(--grid-wide); }

/* ---- relationship spacing --------------------------------------------- */
/* An eyebrow, its heading and its paragraph are ONE idea and are spaced
   tightly. Space between ideas is larger than space within one - that is the
   whole of it, and using a single uniform gap is what made this look off. */
.orca-group { display: flex; flex-direction: column; align-items: inherit; }
.orca-group > .orca-eyebrow + * { margin-top: var(--tight); }
.orca-group > h1 + *, .orca-group > h2 + *, .orca-group > h3 + * { margin-top: var(--snug); }
.orca-group > p + p { margin-top: var(--snug); }
.orca-group > p + .orca-btns, .orca-group > .orca-lead + .orca-btns { margin-top: var(--loose); }
.orca-group > .orca-duo-list + .orca-btns { margin-top: var(--loose); }
.orca-group > h2 + .orca-duo-list { margin-top: var(--snug); }
.orca-blocks { display: flex; flex-direction: column; gap: var(--block); }

/* ---- surfaces --------------------------------------------------------- */
.orca-ground   { background: var(--ground); }
.orca-recessed { background: var(--recessed); }
.orca-statement{ background: var(--brand); color: var(--reversed); }
.orca-statement .orca-eyebrow { color: rgba(255,255,255,.75); }
.orca-statement p { color: rgba(255,255,255,.88); }

/* HEADINGS ON A LOUD BAND ARE REVERSED, AND SAYING IT ONCE IS NOT ENOUGH.
   The surface set its own color and let the headings inherit — but Elementor's kit
   writes the heading color DIRECTLY onto the widget
   (.elementor-widget-heading .elementor-heading-title { color: brand }), and a
   direct rule beats an inherited one however loud the parent is. The result
   shipped: a brand-blue headline on a magenta band, the exact
   brand-on-accent the rule forbids.

   Two classes on the left of the descendant beats Elementor's two, so this
   wins on specificity rather than on !important. Every level, because a band
   is not always headed by an h2. */
.orca-section.orca-statement h1, .orca-section.orca-statement h2, .orca-section.orca-statement h3,
.orca-section.orca-statement h4, .orca-section.orca-statement h5, .orca-section.orca-statement h6,
.orca-section.orca-statement .elementor-heading-title,
.orca-section.orca-accent-cta h1, .orca-section.orca-accent-cta h2, .orca-section.orca-accent-cta h3,
.orca-section.orca-accent-cta h4, .orca-section.orca-accent-cta h5, .orca-section.orca-accent-cta h6,
.orca-section.orca-accent-cta .elementor-heading-title,
.orca-section.orca-photographic h1, .orca-section.orca-photographic h2, .orca-section.orca-photographic h3,
.orca-section.orca-photographic .elementor-heading-title {
  color: var(--reversed);
}

/* ---- buttons ---------------------------------------------------------- */
.orca-btns { display: flex; gap: var(--snug); flex-wrap: wrap; align-items: center; }
/* 8 and 32, both on the spacing scale - the previous 15/30 was on neither.
   A wide, shallow button: the horizontal padding is what makes it read as a
   button, and the vertical padding was only ever making it tall.

   inline-flex rather than inline-block at every width, so the label stays
   centered when the mobile rule below raises the height. One layout mode, not
   one per breakpoint. */
.orca-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 32px; border-radius: var(--radius);
  font-size: 16px; font-weight: 600; text-decoration: none;
  background: var(--accent); color: #fff; border: 2px solid var(--accent);
  transition: background .2s ease, color .2s ease;
}
/* THE HOVER IS A STYLE SWAP (Nick, 30 Aug): solid hovers to its own outline,
   outline hovers to solid - text by contrast - the border NEVER changes and
   is 2px everywhere, so the swap costs no layout shift. The built site says
   the same in utility-css.orca-ts; this is the preview agreeing. */
.orca-btn:hover { background: transparent; color: var(--accent); }
.orca-btn-out { background: transparent; color: var(--brand); border-color: var(--brand); }
.orca-btn-out:hover { background: var(--brand); color: #ffffff; }
.orca-statement .orca-btn { background: #fff; color: var(--brand); border-color: #fff; }
.orca-statement .orca-btn:hover { background: transparent; color: #fff; }
.orca-statement .orca-btn-out { background: transparent; color: #fff; border-color: #fff; }
.orca-statement .orca-btn-out:hover { background: #fff; color: var(--accent); }
.orca-photo .orca-btn-out { color: #fff; border-color: #fff; }
.orca-photo .orca-btn-out:hover { background: #fff; color: var(--ink); }

/* ---- photographic bands ----------------------------------------------- */
/* Vertical placement is a rule, not a system setting, and the two cases differ:

   THE OPENING HERO sits at the BOTTOM. It is the tallest thing on the site and
   the only one whose photograph has room to be a photograph - bottom-aligned
   text leaves the top two-thirds of the image alone, and it puts the headline
   next to the fold, which is where the eye already is when the page settles.
   It is also where the scrim is darkest, so the two agree.

   EVERY LATER BAND is CENTERED. A later band is half the height, so there is no
   spare image to protect, and bottom-aligned text in a short band reads as
   text that has fallen over rather than text that has been placed. */
.orca-photo {
  position: relative; display: flex; align-items: center;
  background-size: cover; background-position: center;
  color: var(--reversed); padding: var(--pad) var(--gutter);
}
.orca-photo.orca-hero { align-items: flex-end; }
.orca-photo::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top right, rgba(0,0,0,.65) 0%, rgba(0,0,0,.35) 45%, rgba(0,0,0,0) 80%); }
/* Content sits in the same 1200px column as every other section. */
.orca-photo .orca-inner { position: relative; z-index: 1; }
.orca-photo .orca-group {  }

/* BUTTONS FOLLOW THE TEXT ABOVE THEM. The group centers its text but the
   button row is a 100%-wide flex box, so align-items cannot move its
   contents — the hero shipped centered words over left-parked buttons. Every
   other centered context (.orca-solo, mobile) already carries this rule; the
   photographic band was the missing joint. */

.orca-photo p { color: rgba(255,255,255,.92); }
.orca-photo .orca-eyebrow { color: rgba(255,255,255,.8); }
.orca-hero { min-height: 75vh; }
/* The COMPACT title band, ~14vh. For utility pages (recipes.orca-ts names them —
   COMPACT_TITLE_RECIPES): the locations index, the checkout funnel, legal.
   Their titles are labels, not arrivals, and a 30vh band before a list of
   addresses is throat-clearing. */
.orca-title-band.orca-compact { min-height: 14vh; }
.orca-title-band.orca-compact h1 { font-size: clamp(1.5rem, 2.5vw, 2.1rem); }

/* ---- interior title band ---------------------------------------------- */
/* A PHOTOGRAPH, but a short one. ~30vh against the hero's
   75vh.

   The treatment is the hero's - full-bleed image, scrim, reversed text - and
   the height is not, because height is what makes the opening hero the opening
   hero. An interior page is reached deliberately: someone at /about already
   knows where they are, and a full-height photograph delays the thing they came
   for. Borrow the language, not the drama.

   NO PHOTOGRAPH, NO PHOTOGRAPHIC BAND. Where the page has no image of its own
   it falls back to Ground rather than reaching for stock to fill the slot -
   invariant 8, and the same rule that turns the contact map into a photograph
   when there is no address. */
.orca-title-band {
  position: relative; display: flex; align-items: center;
  min-height: 30vh;
  padding: var(--pad) var(--gutter);
  background: var(--ground);
}
.orca-title-band h1 { font-size: clamp(30px, 4.4vw, 46px); }
.orca-title-band .orca-lead { margin-top: var(--snug); }

/* The photographic variant. Same scrim as the hero, so a headline is legible
   over an unknown image by the same means in both places. */
/* BOTTOM-ALIGNED COPY AND ITS OWN SCRIM (Nick's hand-restyle, 2 Sep). The
   title band borrowed the hero's directional scrim; his reference darkens
   only the bottom where the copy now sits. Two stops, transparent to 50%
   black -- heavier than his 20% floor because Orca cannot see the
   photograph it will be handed, and white type over a bright sky at 20% is
   unreadable. The template ALSO sets the scrim as an Elementor background
   overlay (kit custom CSS is Pro-only, and a CSS-only scrim is no scrim at
   all without it), so the ::after is gated: exactly one of the two paints. */
.orca-title-band.orca-photo { color: var(--reversed); background-size: cover; background-position: center; justify-content: flex-end; }
.orca-title-band.orca-photo:not(:has(.elementor-background-overlay))::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0) 35%, rgba(0,0,0,.5) 100%); }
.orca-title-band.orca-photo .orca-inner, .orca-title-band.orca-photo .elementor-container { position: relative; z-index: 1; }
.orca-title-band.orca-photo p { color: rgba(255,255,255,.92); }
.orca-title-band.orca-photo .orca-eyebrow { color: rgba(255,255,255,.8); }

/* THE QUIET VARIANT. A tinted band with a faint pattern on it, and ordinary
   ink - no photograph, no scrim, no reversed text.

   Drawn in CSS rather than served as an image. A texture file is a request, a
   thing that can 404, and a fixed resolution that has to be decided in advance;
   two gradients are none of those and are the same three lines at any width.

   Three layers, each doing one job:
     1. a soft off-center highlight, so the band is not a dead flat rectangle;
     2. hairlines at 135 degrees, 6px apart at 4.5% - close to the threshold of
        visible, which is the point. A texture you notice is a pattern, and a
        pattern behind a headline is competing with it;
     3. the tint itself, mixed from the site's own chrome color so the band
        belongs to this site rather than looking like a stock paper texture. */
.orca-title-band.orca-texture {
  background-color: var(--band-tint);
  background-image:
    radial-gradient(120% 90% at 12% 0%, rgba(255,255,255,.6), transparent 62%),
    repeating-linear-gradient(135deg,
      rgba(var(--chrome-rgb), .045) 0 1px,
      transparent 1px 6px);
  border-bottom: 1px solid var(--hairline);
}

.orca-band { min-height: 38vh; }

/* ---- components ------------------------------------------------------- */
/* EQUAL HEIGHT IS NOT A DEFAULT YOU CAN ASSUME. align-items:stretch is the
   initial value, so this looked handled — but the cards are Elementor
   containers, and Elementor writes its own alignment onto them, which is how a
   row of three shipped with the middle one hanging lower than its neighbours.
   Said here explicitly, on both halves of the joint: the row stretches its
   children, and each card fills what it is given. */
/* A GRID, NOT A FLEX ROW (27 Aug, after two rounds of flexbox refusing to
   stretch Elementor containers). Grid makes both promises structurally:
   every column is the same 1fr track, so cards are equal width even on a
   short wrapped row, and grid items stretch to their row by default, so
   cards are equal height without a rule Elementor can override. The column
   count rides in as a class from the template (2-4 by item count; five or
   six wrap as 3+2 / 3+3, seven or eight as 4+3 / 4+4). The three structural
   properties carry !important because the cards are Elementor containers
   and Elementor writes its own flex display and gap onto them. */
/* HALF TRACKS, AND EVERY CARD SPANS TWO. Laid out this way the row is
   identical to whole tracks - the arithmetic cancels exactly, because the
   extra gap a card swallows in the middle is the gap the missing track took -
   and it buys the one thing whole tracks cannot do: a last row of two centered
   under three columns has to start half a column in. */
.orca-cards {
  display: grid !important;
  grid-template-columns: repeat(var(--cards-track, 8), minmax(0, 1fr)) !important;
  gap: var(--snug) !important;
  align-items: stretch;
}
.orca-cards-cols-2 { --cards-track: 4; }
.orca-cards-cols-3 { --cards-track: 6; }
.orca-cards-cols-4 { --cards-track: 8; }
/* Elementor's per-element width (the old flex share) must not shrink a card
   inside its track; the track IS the width now. */
/* THE SPAN RIDES ON THE END, never the start: a shorthand span sets the
   START to a span and leaves the end auto, so the moment a tail rule names a
   start line the card collapses to one half-track. Measured live, 27 Aug. */
.orca-cards > * { grid-column-end: span 2; width: auto !important; max-width: none !important; min-height: 0; }

/* THE SHORT LAST ROW FOLLOWS THE HEADING (Nick, 27 Aug). Under a centered
   heading, a last row hard against the left margin is the small wrongness
   everyone sees and nobody names. Each card the row is missing pushes it half
   a column in, which is why the tracks above are halves. The template counts
   the tail and names it, because a stylesheet cannot count its own children. */
.orca-cards-center-tail.orca-cards-tail-1-2 > *:nth-last-child(1) { grid-column-start: 2; }
.orca-cards-center-tail.orca-cards-tail-1-3 > *:nth-last-child(1) { grid-column-start: 3; }
.orca-cards-center-tail.orca-cards-tail-2-3 > *:nth-last-child(2) { grid-column-start: 2; }
.orca-cards-center-tail.orca-cards-tail-1-4 > *:nth-last-child(1) { grid-column-start: 4; }
.orca-cards-center-tail.orca-cards-tail-2-4 > *:nth-last-child(2) { grid-column-start: 3; }
.orca-cards-center-tail.orca-cards-tail-3-4 > *:nth-last-child(3) { grid-column-start: 2; }

/* COMPACT: A WRAPPED CARD TURNS ON ITS SIDE (Nick, 27 Aug). Five picture
   cards in three columns leave a torn second row - two tall cards beside a
   hole. Turned sideways, the face takes a third and the words two thirds, two
   to a row, and the set reads as a list somebody meant to write. The template
   decides this, and only for cards that HAVE a face: a plain text card has
   nothing to put in that third. The COLUMN COUNT IS NOT ITS BUSINESS - the
   grid still runs up to four across, the cards inside it just lie down. */
.orca-cards-compact .orca-card {
  display: grid !important;
  grid-template-columns: 1fr 2fr;
  align-items: stretch;
  min-height: 132px;
}
/* The face is the containing block, so the photograph can fill a cell whose
   height comes from the words beside it rather than from its own ratio. */
.orca-cards-compact .orca-card > *:first-child { position: relative; min-width: 0; height: auto; }
.orca-cards-compact .orca-card img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover;
}
/* A CARD WITH NO FACE TAKES THE WHOLE WIDTH. One dish in a set can be waiting
   for its photograph, and a lone body in a two-column card would otherwise be
   squeezed into the third the missing picture left (seen live, 27 Aug: a
   five-card set where the fifth had no photo yet). */
.orca-cards-compact .orca-card > *:only-child { grid-column: 1 / -1; }
/* An icon or a numeral has no cropping to do - it sits in the middle of its
   third instead. */
.orca-cards-compact .orca-card .orca-icon,
.orca-cards-compact .orca-card .orca-num {
  display: flex; align-items: center; justify-content: center;
  height: 100%; padding: var(--snug); margin: 0;
}
.orca-card {
  flex: 1 1 0; min-width: 0; background: #fff; border: 1px solid var(--hairline);
  border-radius: var(--radius); overflow: hidden;
  display: flex; flex-direction: column;
  /* A card is a thing sitting ON the page, so it gets the lift. The border
     stays: on a tinted surface the shadow alone does not define the edge. */
  box-shadow: var(--shadow-sm);
}
/* NO HOVER STATE. These cards are not links. A thing that reacts to the cursor
   is promising it can be pressed, and a card that lifts and then does nothing
   is a small lie told to every visitor who tries it. Hover belongs to anchors
   and buttons, and nothing else. */
a.orca-card, button.orca-btn { transition: box-shadow .18s ease, transform .18s ease; }
button.orca-btn { cursor: pointer; font-family: inherit; }
a.orca-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
/* THE WHOLE CARD IS THE ANCHOR (contact-multi standard, 27 Aug). The card
   renders as an a; the text must not go link-blue, and the affordance the old
   title-link rule worried about is the hover: lift plus an accent border. */
a.orca-card { color: inherit; text-decoration: none; }
a.orca-card:hover { border-color: var(--accent); }
/* A photograph at the top of the card. Three text cards in a row are three
   paragraphs wearing borders; a picture is the thing people actually look at.

   Ordinary landscape, never square: a card is already a narrow column, and a
   square picture at the top of one pushes the heading that explains it too far
   down. Square crops belong in the two-column rows, where the picture has half
   a page to fill. */
.orca-card img {
  width: 100%; aspect-ratio: 1.0000;
  object-fit: cover; display: block;
}
/* flex:1 on the body is what makes the equal height MEAN something: the body takes the
   slack, so two cards of different lengths end up the same height with their
   text top-aligned, rather than one card padded out at the bottom. Padding is
   --snug rather than --loose: at --loose a three-word card was mostly margin. */
.orca-card-body { padding: var(--snug); display: flex; flex-direction: column; flex: 1 1 auto; }
.orca-card h3 + p { margin-top: var(--tight); }
.orca-card p { font-size: 16px; color: var(--ink-muted); max-width: none; }
/* The icon variant's face: a registry SVG (templates/icons.orca-ts), stroked in
   currentColor so the accent colors it, sitting where the image face would.
   line-height 0 stops the wrapping text widget adding a phantom text row. */
.orca-card .orca-icon { padding: var(--loose) var(--loose) 0; line-height: 0; }
/* 48px AT 1.35. At 44 and 1.6 the icon is a bullet that wandered up from the
   list it replaced; a card whose picture is smaller than its heading has not
   become a card. The stroke weight is set here rather than in the markup so
   one number governs every icon in the registry. */
.orca-card .orca-icon svg { width: 48px; height: 48px; color: var(--accent); stroke-width: 1.35; }

/* The actionable section under the hero: photograph on one side, the two
   things you want pressed on the other. */
.orca-feature { display: flex; gap: clamp(32px, 5vw, 80px); align-items: center; }
.orca-feature > * { flex: 1 1 0; min-width: 0; }
/* Near-square, and the SAME ratio the duo band uses - they are one situation,
   a picture beside a block of text, so they take one value. The cap stops a
   1:1 crop becoming a 900px wall on a wide monitor: past that height the
   picture crops instead of growing. */
.orca-feature img, .orca-split img {
  width: 100%; aspect-ratio: 1.0000;
  max-height: 62vh; object-fit: cover;
  border-radius: var(--radius); display: block;
  /* A photograph on a white ground has no edge of its own. The shadow gives it
     one without a border, which would fight the image. */
  box-shadow: var(--shadow-md);
}
.orca-feature.orca-rev { flex-direction: row-reverse; }

.orca-split { display: flex; gap: clamp(32px, 5vw, 80px); align-items: center; }
.orca-split > * { flex: 1 1 0; min-width: 0; }

/* A grid, not a flex row, because a photo grid is the one place invariant 5
   does not apply: photographs are not a row of content blocks that has to
   become a column, they are a set. One photograph per screen on a phone turns
   a nine-image grid into nine screens of scrolling and reads as nine separate
   statements. Two columns keeps it a set. */
.orca-gallery { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--snug); }
.orca-gallery img {
  width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: var(--radius); display: block; box-shadow: var(--shadow-sm);
}

/* --- The menu, and Elementor's own gallery ---------------------------------
   APPEARANCE ONLY. Neither of these sets a column count or a direction: the
   menu's columns are the container's flex settings and the gallery's are the
   widget's own gallery_columns, so an owner can change either in the editor
   without anybody touching CSS. The rule that made that necessary is two doors
   up — .orca-gallery is a CSS grid, and a grid beats a container's flex, which is
   how a photograph ended up 111px wide inside a 357px cell. */

/* Elementor's gallery widget carries or-photos, deliberately NOT or-gallery
   above, so the grid does not take the layout back off the widget. */
.orca-photos img {
  width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: var(--radius); display: block; box-shadow: var(--shadow-sm);
}

/* THE DOTTED LEADER, which is the whole visual idea of a menu: it ties the
   dish to its price across the gap, so the eye does not have to travel back.
   Elementor's price-list widget already puts the title, the leader and the
   price in one header — this only colors it. */
/* THE DIETARY LEGEND. Quiet, under the list, and text throughout: the marks
   are letters, so the key is letters. Never a row of glyphs. */
.orca-diet-key { color: var(--ink-muted); font-size: 14px; }
.orca-diet-key b { color: var(--ink); font-weight: 700; }

/* THE FREESTANDING TREATMENT (Nick, 30 Aug): every photograph that stands on
   the page - beside a menu, in a feature, in a split - takes the same radius
   and quiet shadow, so the pictures read as one set. Full-bleed bands (duo,
   photo-band, hero) are the page itself and take neither. */
.orca-menu-media img {
  width: 100%; object-fit: cover; display: block;
  border-radius: var(--radius); box-shadow: var(--shadow-md);
  /* SQUARE, BY RULE. The balance arithmetic in templates/menu.orca-ts stands in
     PHOTO_UNITS dishes for this picture, and a natural-aspect image made
     that number a guess - a portrait shot blew past it and the columns
     ended ragged (Nick, 30 Aug). The crop and the constant are one
     decision: change one, change both. */
  aspect-ratio: 1 / 1;
}
/* TEN, NOT TWENTY. Elementor writes its default item gap per element at
   (0,2,0); importance is the one thing that outranks it, and the widget's own
   space_between setting is also set to 10 so a regenerated page agrees. */
.orca-price-list li:not(:last-child) { margin-bottom: 10px !important; }
.orca-price-list .elementor-price-list-item { padding: 0; }
.orca-price-list .elementor-price-list-header {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px;
}
/* THE PRICE WEARS THE DISH NAME'S EXACT STYLE (Nick, 30 Aug) - one shared
   declaration, and both INHERIT size and color from the header they share,
   so they cannot drift apart whatever the widget's own defaults say. The
   family comes from the Subheads token in utility-css, for both. */
.orca-price-list .elementor-price-list-title,
.orca-price-list .elementor-price-list-price { font-weight: 600; font-size: inherit; color: inherit; }
.orca-price-list .elementor-price-list-title { white-space: normal; }
.orca-price-list .elementor-price-list-separator {
  flex: 1 1 auto; border-bottom: 1px dotted var(--hairline); min-width: 18px;
}
.orca-price-list .elementor-price-list-price { font-variant-numeric: tabular-nums; white-space: nowrap; }
.orca-price-list .elementor-price-list-description {
  color: var(--muted); margin: 0;
  /* NO READING MEASURE INSIDE A LIST COLUMN (Nick, 30 Aug: "remove
     max-width paragraphs on menu list items"). The global p rule caps prose
     at var(--measure) - right for an article, wrong here: the column is
     already narrower than the measure is generous, so the cap only wrapped
     "Add bacon or ham...$2.95" onto ragged extra lines. The column bounds
     the line; the paragraph fills it. */
  max-width: none;
}
/* The dish and its description are ONE unit and must not break across a
   column. A dish name at the foot of the left column with its ingredients at
   the head of the right is the specific failure a two-column menu produces. */
.orca-menu-col .elementor-price-list > li { break-inside: avoid; page-break-inside: avoid; }

/* --- The bones, 18 August --------------------------------------------------
   Enough to be legible and judged. The look is Nick's to set in Elementor and
   hand back; nothing here decides a column count or a direction, for the same
   reason as the menu above. */

/* Jump links. ONE LINE, NEVER TWO — a wrapped jump bar is a paragraph of
   links. Past what fits it scrolls sideways, which is a known gesture on a
   phone and the only honest answer to fourteen courses. */
/* COMPACT, AND SAID WITH !important: the band arrives with Elementor's own
   per-element section padding at (0,3,0), which a plain class cannot reach -
   so the old var(--snug) rule silently lost and the strip wore the full
   section rhythm around one row of chips ("the padding/height is too much",
   Nick, 27 Aug). A jump bar is chrome, not a section. */
.orca-nav-strip { padding-top: 10px !important; padding-bottom: 10px !important; min-height: 0 !important; gap: 0 !important; }
/* AND THE LAYERS INSIDE IT. The band's 10px cap was winning and the strip was
   STILL 110px tall (Nick, 30 Aug), because the inner and the jumps row are
   Elementor containers too, each wearing Elementor's own default padding -
   three nested paddings around one row of chips. Chrome carries exactly one:
   the band's. */
.orca-nav-strip .orca-inner, .orca-nav-strip .orca-jumps {
  padding-top: 0 !important; padding-bottom: 0 !important; min-height: 0 !important;
}
/* The behavior widget is a script in a box; the box must cost no height and
   no flex gap. display:none removes it from layout and stops nothing - the
   script has already run by the time paint happens. */
.orca-strip-behavior { display: none !important; }
/* GRABBABLE, THE WHOLE BAND: the strip's script pans the chip row under a
   mouse drag anywhere on the bar (Nick, 2 Sep), so the cursor says so on the
   band's padding too, and a drag must not smear a text selection behind it. */
.orca-nav-strip { cursor: grab; user-select: none; }
.orca-jumps { display: flex; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; align-items: center; width: 100%; }
.orca-jumps::-webkit-scrollbar { display: none; }
/* CENTERED WITH AUTO MARGINS, not justify-content. The strip is middle
   justified in both axes (Nick, 30 Aug) - but justify-content: center on an
   overflowing flex row clips BOTH ends and the first chips become
   unreachable, which is exactly the cut-off "…DICT 'BENNIES'" on staging.
   Auto margins center when the chips fit and collapse to zero when they
   overflow, so the row starts at the left edge and scrolls. */
.orca-jumps > :first-child { margin-left: auto; }
.orca-jumps > :last-child { margin-right: auto; }
/* CHIPS REFUSE TO SHRINK. They are Elementor containers, which default to
   flex-shrink with min-width 0 - so ten categories compressed every chip to
   a sliver and the nowrap labels printed on top of each other (Nick's phone
   and tablet screenshots, 27 Aug). Rigid chips are what make the overflow
   above actually scroll instead of squeeze. */
.orca-jumps > * { flex: 0 0 auto !important; min-width: max-content; }
/* Centered while it fits, scrollable from the FIRST chip when it does not:
   auto margins collapse to zero on overflow, where justify-content center
   would push the left end outside the scrollable area unreachably. */
.orca-jumps > *:first-child { margin-left: auto; }
.orca-jumps > *:last-child { margin-right: auto; }
.orca-jump a {
  display: inline-block; white-space: nowrap; text-decoration: none;
  font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-muted); padding: 8px 14px; border-radius: 999px;
}
/* QUIET BY DEFAULT, LOUD ONLY WHERE YOU ARE. Ten accent pills in a row is ten
   things shouting; the strip answers "where am I" only if exactly one chip
   does. Hover is a whisper (the tint); current is the accent, set by the
   strip's own scroll-spy as aria-current — an attribute rather than a class
   because it is also the word a screen reader says out loud. */
.orca-jump a:hover { color: var(--ink); background: var(--band-tint); }
/* THE WARMER of brand and accent - see stripLoud above. On a menu the strip
   sits over food photography and a tinted band; the hotter, more saturated
   accent shouted at both, and the warmer color reads as part of the meal
   (Nick, 30 Aug). */
.orca-jump a[aria-current] { color: #fff; background: var(--brand); }
/* STICKS UNDER THE CHROME, not behind it. The offset is the header's CURRENT
   height, published as --chrome-h, because a hard-coded number was correct
   exactly once — see the playbook, section 3. */
.orca-nav-strip.orca-stick { position: sticky; top: var(--chrome-h, 0px); z-index: 40; }
/* A JUMP HAS TO LAND BELOW THE CHROME. The target section slides up under the
   pinned header and the stuck strip unless it keeps their combined height as
   scroll margin. Both variables are published by the strip's script and both
   fall back to 0, so the rule costs nothing on a page with no strip. */
.orca-section[id] { scroll-margin-top: calc(var(--chrome-h, 0px) + var(--strip-h, 0px) + 16px); }
/* Smooth, unless the reader's OS asked for no animation. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* One photograph, full bleed. */
.orca-photo-band { display: flex; align-items: center; position: relative; }
.orca-photo-band .orca-inner { text-align: center; position: relative; z-index: 1; }
/* ONE SCRIM, AND IT IS THE DIRECTIONAL ONE. Drawn only where there are words:
   has-copy is set by the template when the band carries any. */
.orca-photo-band.orca-has-copy::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top right, rgba(0,0,0,.65) 0%, rgba(0,0,0,.35) 45%, rgba(0,0,0,0) 80%); }

/* Somebody else's application. A HARD EDGE rather than a blend: a
   half-restyled embed reads worse than a clean seam. */
.orca-embed { width: 100%; border-radius: var(--radius); overflow: hidden; }
.orca-embed iframe { display: block; width: 100%; border: 0; }
/* THE ORDER PAGE'S EMBED FILLS ITS BAND. The band is already full-bleed and
   viewport-tall (the template sets both), but the ordering plugin sizes its
   own iframe to a fixed data-height and boxes its wrapper — 900 pixels of
   storefront floating inside a 100vh band, which is the half-followed rule
   caught on 25 August: the rule reached the band and stopped at the plugin.
   The plugin writes inline heights, so !important here is load-bearing. */
.orca-embed-fullbleed .orca-embed { border-radius: 0; }
/* NO MINIMUM HEIGHT. A 600px floor was here to stop a collapsed embed, and it
   quietly contradicted the rule it sat next to: on a short laptop or a phone
   in landscape it is TALLER than the viewport, so the bottom of the storefront
   sits below the fold — the exact thing "always in view" forbids. The height
   above is explicit, so there is nothing left to collapse. */
.orca-embed-fullbleed .olo-embed,
.orca-embed-fullbleed .olo-embed iframe {
  width: 100% !important; max-width: none !important; margin: 0 !important;
  /* NO HEIGHT HERE ANY MORE. The plugin's embed.orca-js measures the iframe's
     REAL distance from the top -- admin bar, topbar, header, whatever is
     actually there -- and sizes to the viewport below it. This rule used to
     force 100vh minus a variable whose 68px fallback undershot the real
     header stack by ~80px, so the storefront's cart bar hung below the fold
     ('iframe getting cut off' -- Nick, 2 Sep). Two sizers, one blind:
     the sighted one owns the height. */
}
/* AND dvh WHERE IT EXISTS. On a phone, 100vh is the viewport with the browser
   chrome hidden, so an embed sized to it hangs a URL bar's worth below the
   fold until you scroll. 100dvh is the honest number. Its own rule, after the
   vh one, so a browser without dvh keeps the fallback rather than dropping
   the whole declaration block. */


/* CARDS INSIDE THE CONTACT PANEL. Stacked, never a row: they live in half a
   panel beside the map, and two columns in that space is four words a line.
   Bordered rather than filled, because the panel is already a surface and a
   card on a card reads as a mistake. */
.orca-contact-card {
  border: 1px solid var(--hairline); border-radius: var(--radius);
  padding: var(--snug);
}
.orca-contact-card h3 { font-size: 17px; }
.orca-contact-card h3 a { color: inherit; text-decoration: none; }
.orca-contact-card h3 a:hover { color: var(--brand); text-decoration: underline; }
.orca-contact-card p { font-size: 16px; color: var(--ink-muted); }

/* Running text. THE MEASURE IS THE POINT — a paragraph running the full grid
   is unreadable, and that is what happens by default. */
/* PRETTY, NEVER BALANCE (the rulebook's own line): pretty rescues the last
   line's orphan without re-flowing the whole heading between widths. */
.orca-group h1, .orca-group h2, .orca-group h3, .orca-panel h2, .orca-panel h3 { text-wrap: pretty; }

.orca-prose { max-width: var(--measure); text-align: start; }
.orca-prose > * + * { margin-top: var(--snug); }
.orca-prose h3 { margin-top: var(--loose); }
.orca-prose ul, .orca-prose ol { padding-left: 1.2em; }
.orca-prose a { color: var(--brand); }

/* A LIST ALONE IN A SECTION BECOMES CARDS. At the measure, six short items cap
   at 55ch and leave two thirds of the row empty, which reads as a section that
   failed to load rather than one that was composed. Set by the assembler, and
   only when the list is the whole of the section - a list beside a photograph
   is already sharing its row and stays a list. */
.orca-list-cards { max-width: none; }
.orca-list-cards ul, .orca-list-cards ol {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--snug); list-style: none; padding-left: 0; margin: 0;
}
.orca-list-cards li {
  background: var(--ground); border: 1px solid var(--hairline);
  border-radius: var(--radius); padding: var(--snug) var(--loose);
  box-shadow: var(--shadow-sm);
}
@media (max-width: 767px) {
  .orca-list-cards ul, .orca-list-cards ol { grid-template-columns: 1fr; }
  /* PRICES SIT DIRECTLY UNDER THE NAME ON A PHONE. The dotted leader ties a
     dish to a price ACROSS A GAP; on a narrow column there is no gap worth
     bridging, and a leader squeezed to 18px reads as damage. So the header
     wraps, the leader goes, and the price takes the next line - left aligned,
     because on a phone everything on this list is read down one edge. */
  .orca-price-list .elementor-price-list-header { flex-wrap: wrap; }
  .orca-price-list .elementor-price-list-separator { display: none; }
  .orca-price-list .elementor-price-list-price { flex-basis: 100%; white-space: normal; }
}

/* NO RULE FOR .orca-woo, ON PURPOSE. WooCommerce owns every pixel inside a cart, a
   checkout and an account panel. A half-restyled checkout looks like our page
   right up until somebody is typing card details, which is the worst possible
   place for a visual seam, and it is the one screen where a CSS mistake costs
   a sale rather than a compliment. */


/* ---- the compact checkout (Nick, 2 Sep) -------------------------------- */
/* Billing and shipping in three rows: [first][last] /
   [address][city][state][zip] / [phone][email]. Placement by ORDER plus a
   column span, never an explicit grid row, so a store that turns the
   company field on does not shift the layout. LAYOUT IS OURS, PAINT IS
   NOT: no color, border, type or button styling aims at a cart, checkout
   or account panel. */
.woocommerce-billing-fields__field-wrapper,
.woocommerce-shipping-fields__field-wrapper {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--snug) var(--tight);
  align-items: start;
}
/* A field this rule does not name takes the whole row. */
.woocommerce-billing-fields__field-wrapper > .form-row,
.woocommerce-shipping-fields__field-wrapper > .form-row { grid-column: 1 / -1; }

#billing_first_name_field, #shipping_first_name_field { grid-column: span 6; order: 1; }
#billing_last_name_field,  #shipping_last_name_field  { grid-column: span 6; order: 2; }

#billing_address_1_field, #shipping_address_1_field { grid-column: span 4; order: 3; }
#billing_city_field,      #shipping_city_field      { grid-column: span 3; order: 4; }
#billing_state_field,     #shipping_state_field     { grid-column: span 3; order: 5; }
#billing_postcode_field,  #shipping_postcode_field  { grid-column: span 2; order: 6; }

#billing_phone_field { grid-column: span 6; order: 7; }
#billing_email_field { grid-column: span 6; order: 8; }

/* Everything the store added and this rule has not met -- company, a second
   address line, a country .elementor-kit-834 -- sits after the three rows on a full
   line of its own rather than being squeezed into one. */
.woocommerce-billing-fields__field-wrapper > .form-row:not([id$="_name_field"]):not(#billing_address_1_field):not(#billing_city_field):not(#billing_state_field):not(#billing_postcode_field):not(#billing_phone_field):not(#billing_email_field),
.woocommerce-shipping-fields__field-wrapper > .form-row:not([id$="_name_field"]):not(#shipping_address_1_field):not(#shipping_city_field):not(#shipping_state_field):not(#shipping_postcode_field) { order: 9; }

/* ONE COLUMN ON A PHONE: four fields across 390px is four fields nobody
   can type in. */
@media (max-width: 700px) {
  .woocommerce-billing-fields__field-wrapper,
  .woocommerce-shipping-fields__field-wrapper { display: block; }
}

/* NO SHAPE DIVIDERS. Business separates Recessed from Ground with a gradient
   instead — same chunking job, impossible to date, one background declaration
   rather than a clip-path. See recessedEdge in design-systems.orca-ts.

   The clip-path version lived here until 12 August 2026, guarded by a
   sys.orca-shapeDividers field that does not exist on DesignSystem — so the guard
   had been evaluating to an empty string since the day dividers were dropped.
   Nothing caught it while the CSS sat in an untyped .orca-mjs; moving it into a .orca-ts
   file surfaced it in one compile. */

/* The top bar is desktop-only. Below this it cannot hold one line, and the
   same facts are in the footer. */
@media (max-width: 1024px) { .orca-topbar { display: none; } }

@media (max-width: 900px) {
  /* Once every row is one column wide, every block is alone in its row - so
     the centering rule above applies to all of them. */
  .orca-group { align-items: center; text-align: center; }
  .orca-group p { margin-inline: auto; }
  .orca-btns { justify-content: center; }

  /* EXCEPT WHERE THE SECTION CONTAINS A LIST.

     A list is read down its left edge. Centering it breaks the one thing that
     makes it a list - every item starting in the same place - and an icon list
     is worse still, because the icons stop forming a column and scatter. The
     ragged left edge that results reads as broken rather than as centered.

     The whole section opts out, not just the list, because a centered heading
     above a left-aligned list is a third alignment nobody chose. The has-list
     class is derived from the rendered markup, never declared by hand. */
  .orca-has-list .orca-group,
  .orca-has-list .orca-group p { text-align: left; margin-inline: 0; }
  .orca-has-list .orca-group { align-items: flex-start; }
  .orca-has-list .orca-btns { justify-content: flex-start; }

  /* invariant 5: rows stack, never a 2 + 1 orphan */
  .orca-icon-cards, .orca-split, .orca-feature, .orca-feature.orca-rev, .orca-duo, .orca-contact-split { flex-direction: column; }
  /* The card grid narrows to two columns here; one column is the phone
     rule further down. The tail the template counted was for the desktop
     column count, so it is dropped and re-decided: at two columns the tail is
     a parity, which the template also names. */
  .orca-cards { --cards-track: 4; }
  .orca-cards > * { grid-column-start: auto; }
  .orca-cards-center-tail.orca-cards-odd > *:last-child { grid-column-start: 2; }
  /* Two across, not one. A column of four big numerals is four screens of
     scrolling for four facts meant to be taken in together.

     The separator stays VERTICAL, between the two columns - odd items open a
     row, even items are divided from the one beside them. A horizontal rule
     between rows would be a different component: it would group the figures
     into pairs, which is a claim about them that is not true. */
  .orca-figures { flex-wrap: wrap; row-gap: var(--block); justify-content: flex-start; }
  .orca-figure { flex: 0 0 50%; padding: 0 var(--snug); border-left: 1px solid var(--hairline); }
  .orca-figure:nth-child(odd) { border-left: 0; padding-left: 0; }
  .orca-figure:last-child { padding-right: 0; }
  /* Two columns, never one. An odd photograph spans both rather than sitting
     alone in a half-width slot, which is the 2 + 1 orphan invariant 5 forbids
     wearing a different hat. */
  .orca-gallery { grid-template-columns: 1fr 1fr; }
  .orca-gallery img:last-child:nth-child(odd) { grid-column: 1 / -1; aspect-ratio: 16/10; }
  .orca-contact-split .orca-map { flex: none; min-height: 240px; }
  /* The footer keeps its left edge on a phone. It is mostly lists, and a list
     is read down its left edge - the same reason has-list exists. */
  .orca-foot-top { flex-direction: column; gap: var(--loose); }
  .orca-foot-legal-row { flex-direction: column; align-items: flex-start; gap: var(--snug); }
  .orca-foot-legal { margin-left: 0; }
  /* The band goes edge to edge; its TEXT still lines up with every other
     section's text. A full-width background is not a license to move the
     content out of the page's grid. */
  .orca-duo-block { padding: var(--pad) var(--gutter); }

  /* The inline nav becomes a trigger, and the CTA leaves the header for the
     bottom of the screen - see .orca-cta-bar. The header is now identity and
     navigation, nothing else. */
  .orca-nav { display: none; }
  /* THE COMPACT HEIGHT, from the first paint. A phone header holds a small
     logo and one trigger; the full 68px bar around them read as dead space
     ("mobile header has big empty space" - Nick, 30 Aug). Same number as the
     scrolled state, so nothing jumps when the pin arrives. */
  .orca-site-header { height: var(--header-h-compact); }
  .orca-site-header .orca-logo img { max-height: calc(var(--header-h-compact) - 12px); }
  /* LOGO HARD LEFT, TRIGGER HARD RIGHT, NOTHING BETWEEN (Nick, 30 Aug). The
     desktop bar packs three explicit columns from the left - 18 / 60 / 22 -
     and that is right when all three exist. On a phone the columns collapse
     to auto width, the row gap goes to zero, and space-between hands ALL the
     slack to the middle - the one case where space-between is correct,
     because only the two edges hold anything. !important because Elementor
     writes the desktop widths as element-specific rules that outrank a bare
     class. */
  .orca-site-header > .orca-inner { justify-content: space-between; gap: 0; }
  .orca-site-header .orca-brand, .orca-site-header .orca-header-right, .orca-site-header .orca-nav {
    width: auto !important; flex: 0 0 auto;
  }
  /* ON A BUILT SITE THE TRIGGER IS ELEMENTOR'S OWN - chrome.orca-js targets
     .elementor-menu-toggle first, and it lives INSIDE the nav widget. So the
     nav column does not vanish: it collapses to exactly that trigger, hard
     against the right edge. The horizontal menu inside it is what goes. The
     bare display:none on .orca-nav above still covers the preview, whose nav is
     plain links with its own trigger markup in .orca-header-right. */
  .orca-nav:has(.elementor-menu-toggle) { display: flex; justify-content: flex-end; }
  .orca-nav .elementor-nav-menu--main { display: none !important; }
  /* The template's own trigger box is a placeholder with nothing in it on a
     built site - Elementor's trigger does the job - and an invisible 44px
     square at the hard right is exactly why the visible trigger sat mid-bar.
     Empty, it goes; the preview's trigger carries an SVG and stays. */
  .orca-nav-toggle:empty { display: none; }
  .orca-nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin-left: auto;
    background: none; border: 0; color: inherit; cursor: pointer;
  }
  .orca-header-cta { display: none; }
  .orca-cta-bar { display: block; }
  /* Clear of the action bar rather than on top of it. */
  .orca-to-top { bottom: 104px; }
  /* NO BODY PADDING (Nick, 27 Aug). The 104px bottom pad cleared the
     floating action bar but showed as a dead band under the footer on
     every phone. Removed on his call; the footer itself carries enough
     bottom padding that only the last few pixels ride behind the bar. */
  /* 8px of padding makes a button about 39px tall, which is under the 44px
     minimum tap target. The PADDING is the design decision and it does not
     change; a floor on the height is added instead, and only here - a mouse
     has no such requirement, so the desktop button stays exactly as drawn. */
  .orca-btn { min-height: 44px; }

  .orca-duo-media { aspect-ratio: 16/10; max-height: none; }


}

/* ---- the top bar ------------------------------------------------------ */
/* Hours, address, phone — on ONE line above everything, desktop only.
   These are reference facts, not an argument: they belong where a returning
   visitor's eye already goes, not occupying the best position on the page
   directly under the hero. Hidden below 1024px, where a single line cannot
   hold them and where the same facts live in the footer instead. */
/* THE RESTAURANT BAR IS THE ACCENT; everyone else gets near-black.
   Restaurant is the system whose loud color IS the identity - the bar reads
   as the awning over the door, and a near-black strip on a café reads as a
   different site's chrome. The standard is Nick's hand-built bar (30 Aug):
   background bound to the kit's global accent. On a built site the template
   carries that binding as a SETTING (site-header.orca-ts); this rule is the same
   color for the preview and the fallback. Business and creative keep
   near-black: a saturated bar across a supplier's page spends the loudest
   color on the least important content. Where the ground is dark the loud
   color goes on the ICONS; on the accent ground the icons go white, because
   accent-on-accent is invisible and two loud colors fight over 15px. */
.orca-topbar {
  position: relative; z-index: 40;
  background: var(--dark); color: #fff;
  /* A FIXED 40px STRIP (Nick's hand-restyle, 2 Sep): zero vertical padding,
     min-height carries the height, facts left and accounts right. */
  font-size: 13px; padding: 0 var(--gutter);
  min-height: 40px; display: flex; align-items: center;
}
/* WIDGETS AT THEIR OWN WIDTH. Elementor widgets default to 100% and two of
   them in a row squish and wrap -- the accounts dropped under the facts. */
.orca-topbar .orca-inner > .elementor-element { width: auto; }
.orca-topbar .orca-topbar-social { margin-left: auto; flex: none; }
.orca-topbar .orca-topbar-social .elementor-social-icons-wrapper { display: flex; flex-wrap: nowrap; }
.orca-topbar .orca-topbar-social .elementor-social-icon { background: transparent; }
/* SIZED HERE AND IN THE MARKUP BOTH. An unsized inline SVG fills its
   container - the staging site drew a map pin the height of the screen before
   the kit CSS landed. The width/height attributes in the template are the
   seatbelt; this is the rule. */
.orca-topbar svg { color: var(--chrome); opacity: 1; width: 15px; height: 15px; flex: none; }
.orca-topbar .orca-inner { display: flex; flex-direction: row; align-items: center;
  justify-content: space-between; gap: var(--loose); width: 100%; }
/* THE TEXT ELEMENTS DIRECTLY, not only by inheritance from the bar. The kit's
   theme style writes the body color onto widget text at higher effective
   priority than a color inherited from .orca-topbar, which is how a red bar
   shipped with near-black words on it (Nick, 30 Aug). The template also
   writes the contrast-decided color inline on the row; these rules are the
   stylesheet agreeing with it. */
.orca-topbar p, .orca-topbar .orca-topbar-item, .orca-topbar a { color: inherit; }
/* THE BUILT bar's inner is an Elementor container, and containers arrive
   wearing Elementor's own default padding - which stacked inside the bar's
   9px and fattened a one-line strip. The bar's padding is the bar's. */
.orca-topbar .orca-inner { padding-top: 0 !important; padding-bottom: 0 !important; min-height: 0 !important; }
/* The BUILT bar's row. On a real site the items live inside one text widget
   (Elementor wraps every widget in its own divs, so flex on .orca-inner would lay
   out the wrappers, not the items); the row div is markup the template
   controls, and it carries the same layout the preview's .orca-inner does. */
.orca-topbar-row { display: flex; align-items: center; gap: var(--loose); min-width: 0; }
.orca-topbar-body { width: 100%; }
.orca-topbar-body p { margin: 0; }
.orca-topbar-item { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.orca-topbar-item svg { flex: none; }
.orca-topbar-right { margin-left: auto; display: inline-flex; gap: var(--snug); }
.orca-topbar a { text-decoration: none; }
.orca-topbar a:hover { text-decoration: underline; }

/* ---- the site header -------------------------------------------------- */
/* Logo left, navigation right, ONE solid button at the far right.
   The button is the header's commercial job and the reason the arrangement is
   worth standardizing: it is the only call to action visible from every scroll
   position on every page. There is exactly one, and it is the same action the
   page's Statement section asks for - two different asks in two places is two
   people arguing.

   THIS SYSTEM SITS THE HEADER ABOVE THE HERO, solid, in one color, at one
     height. Business pages are an argument rather than an image and the header
     is a tool; a tool is more useful sitting still. */
/* HEADER HEIGHT IS A TOKEN, not a consequence of its contents. It has to be a
   known number because the transparent variant offsets the hero by exactly it,
   and because a header that changes height when a nav item is renamed is a
   header that shifts the whole page. */
.orca-site-header .orca-logo img {
  /* The bar is a fixed --header-h and compacts to --header-h-compact, so the
     logo has to fit inside the SMALLER of the two. A client's own artwork is
     the commonest thing that breaks a header, and it arrives at whatever size
     it arrives at, so the ceiling is enforced here rather than trusted. */
  max-height: calc(var(--header-h-compact) - 8px);
  width: auto; object-fit: contain;
}
/* THE LOGO STARTS AT THE LEFT EDGE OF ITS COLUMN, always. Elementor's image
   widget centers itself in its wrapper, so the mark floated mid-way across
   the brand box ("logo should always be left positioned" - Nick, 30 Aug).
   The template writes align: left as a setting; this is the same decision in
   the stylesheet. */
.orca-site-header .orca-brand { justify-content: flex-start; }
.orca-site-header .orca-brand .orca-logo, .orca-site-header .orca-brand .orca-logo-text { text-align: left; }
.orca-site-header.orca-compact .orca-logo img { max-height: calc(var(--header-h-compact) - 12px); }

.orca-site-header {
  /* NOT STICKY AT REST. A header pinned from the first pixel permanently
     covers whatever the page puts at its own top, and the page has no idea the
     header is there. It sits in the document until it has scrolled out of
     view, and only then pins. */
  position: static; z-index: 50;
  display: flex; align-items: center;
  height: var(--header-h); padding: 0 var(--gutter);
  /* Height and color are the only things that change on scroll, and both are
     transitioned so nothing jumps under the reader's eye. */
  transition: height .2s ease, background-color .2s ease, box-shadow .2s ease,
              transform .24s ease;
}
/* PINNED once it has scrolled past its own height — not a round number, so it
   arrives at the moment it would otherwise have left the screen and nothing
   jumps. */
.orca-site-header.orca-pinned { position: fixed; top: var(--iw-pin-top, 0); left: 0; right: 0; }
/* Gone on the way down, back on the way up. Transform rather than display, so
   it slides out rather than disappearing, and so nothing below it reflows.
   Scoped to .orca-pinned: unscoped it drags the resting header off the page.
   THE PIN OFFSET RIDES ALONG - the plugin sets --iw-pin-top under the
   WordPress admin bar, and a header pinned 46px down that slides up by only
   its own height leaves a 46px slice of itself on screen forever ("doesn't
   disappear" - Nick, 30 Aug). Both dialects say the same distance. */
.orca-site-header.orca-pinned.orca-gone { transform: translateY(calc(-100% - var(--iw-pin-top, 0px))); }
@media (prefers-reduced-motion: reduce) {
  .orca-site-header, .orca-to-top, .orca-cta-bar, .orca-nav-panel { transition-duration: .01ms; }
}

/* SOLID, ABOVE THE HERO. One color, no scroll-dependent contrast — AND COMPACT
   FROM THE FIRST PAINT. A transparent header costs the page nothing; a solid
   one pushes the whole page down by its own height before anybody has read a
   word, so it takes the smaller of the two. Same number as the scrolled state,
   so a page that opens solid and a page that has been scrolled are never two
   different heights. */
.orca-site-header { background: var(--ground); border-bottom: 1px solid var(--hairline);
               height: var(--header-h-compact); }
.orca-site-header .orca-logo { color: var(--brand) !important; }
/* --main for the same reason as the over-hero system: the phone panel's
   links are a.elementor-item too, and they belong to chrome.orca-css. */
.orca-site-header .orca-nav a,
.orca-site-header .elementor-nav-menu--main a.elementor-item { color: var(--ink) !important; }

/* COMPACTED. Applied by the one line of script at the foot of the page once
   the reader is 100px in. Solid at every system, because past the hero there
   is no longer a photograph to be transparent over, and a header that stays
   see-through across the body of a page is a header you cannot read. */
.orca-site-header.orca-compact {
  height: var(--header-h-compact);
  background: var(--ground) !important; color: var(--ink);
  box-shadow: var(--shadow-md);
}
.orca-site-header.orca-compact .orca-logo { color: var(--brand) !important; }
.orca-site-header.orca-compact .orca-nav a,
.orca-site-header.orca-compact .elementor-nav-menu--main a.elementor-item { color: var(--ink) !important; }
.orca-site-header.orca-compact .orca-nav a::after { background: var(--chrome) !important; }

/* The BAR spans the window; its CONTENTS sit in the wide grid. */
.orca-site-header > .orca-inner { display: flex; align-items: center; gap: var(--loose); }
.orca-logo {
  font-weight: 800; font-size: 20px; letter-spacing: -.02em;
  text-decoration: none; white-space: nowrap;
}
/* ONE LINE, ALWAYS. The item ceiling is a budget; this is the actual rule. A
   wrapped nav is the 25 August build's fourteen items in five rows, and the
   fix then was to cap the count — which only makes wrapping less likely, not
   impossible: seven short words fit where seven long ones do not.
   nowrap states it, and the gap closes under pressure rather than the bar
   breaking. The browser pass fails a build where the row is not one line. */
.orca-nav {
  display: flex; align-items: center; margin-left: auto;
  flex-wrap: nowrap; min-width: 0;
  gap: clamp(var(--snug), 1.7vw, var(--loose));
}
.orca-nav a {
  position: relative; text-decoration: none; font-size: 16px;
  font-weight: 550; white-space: nowrap; padding: 4px 0;
}
/* An underline that grows from the middle, not a color change: on a
   transparent header over an unknown photograph, a color change may be
   invisible. A line is a line on anything. */
.orca-nav a::after {
  content: ''; position: absolute; left: 50%; right: 50%; bottom: 0; height: 2px;
  background: var(--chrome); transition: left .18s ease, right .18s ease;
}
.orca-nav a:hover::after, .orca-nav a[aria-current="page"]::after { left: 0; right: 0; }
.orca-header-cta { flex: none; }
/* IT SHRINKS ITS PADDING, NEVER ITS HEIGHT. Height is what a thumb finds, and
   a button that loses 6px of it to make room on a narrow bar has stopped being
   a target to save space nobody was short of. Between 900 and 1024 the bar is
   tight and the button is still in it; below 900 the button is not here at all
   - it has moved to the quick action bar. */
@media (max-width: 1024px) {
  .orca-header-cta .orca-btn { padding-left: 20px; padding-right: 20px; }
}
/* The trigger only exists below the nav breakpoint. */
.orca-nav-toggle { display: none; }

/* ---- the mobile call to action ---------------------------------------- */
/* ON A PHONE THE CALL TO ACTION LEAVES THE HEADER ENTIRELY and becomes a
   floating bar at the BOTTOM of the screen.

   The header is the worst place for it on a phone. A one-handed grip puts the
   thumb at the bottom of the device; the top corners are the hardest region to
   reach and the one most likely to need a hand shuffle. Putting the single
   action the site exists to get in the least reachable corner, next to the
   menu trigger it competes with, is a self-inflicted wound.

   So on a phone the header goes back to two things - identity and navigation -
   and the action sits under the thumb, centered, on every screen and every page.

   It reveals on scroll rather than being present from the first frame: the
   hero already carries the same two buttons, so a floating copy over the top of
   them is the same offer twice. */
.orca-cta-bar {
  position: fixed; z-index: 55;
  left: 0; right: 0; bottom: 0;
  display: none;
  padding: var(--snug) var(--gutter) calc(var(--snug) + env(safe-area-inset-bottom, 0px));
  /* Not a solid bar. A fade means the button is legible over whatever happens
     to be behind it without stamping a slab across the bottom of every page. */
  background: linear-gradient(to top, var(--ground) 55%, transparent);
  /* Slides out of the way until earned. */
  transform: translateY(110%); transition: transform .24s ease;
  pointer-events: none;
}
.orca-cta-bar[data-show="true"] { transform: translateY(0); pointer-events: auto; }
.orca-cta-row { display: flex; gap: var(--tight); max-width: 480px; margin: 0 auto; align-items: stretch; }
/* THE BAR IS ACCENT ONLY - no brand color anywhere in it ("mobile action bar
   should only be accent color, no brand color" - Nick, 30 Aug, looking at a
   red button wearing yellow text). The primary is the SOLID button: accent
   fill, ink by contrast (--on-accent). The secondary is the OUTLINE button:
   accent border, accent text, ground fill. Both wear the kit's 2px border so
   the pair reads as the same two buttons the rest of the site uses. The
   !important is deliberate: the primary is a clone of the header CTA and
   arrives wearing whatever button classes the header gave it. */
.orca-cta-primary {
  flex: 1 1 auto; min-width: 0; box-shadow: var(--shadow-md);
  background: var(--accent) !important; color: var(--on-accent) !important;
  border: 2px solid var(--accent) !important;
}
/* Secondary actions are icon-over-label, fixed width. They are the outline
   half of the pair - a shortcut for someone who already knows what they want,
   not a second offer, which is why they carry no fill. */
.orca-quick {
  flex: 0 0 64px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
  min-height: 44px; padding: 6px 2px; border-radius: var(--radius);
  background: var(--ground); border: 2px solid var(--accent);
  color: var(--accent); text-decoration: none; box-shadow: var(--shadow-sm);
}
.orca-quick span { font-size: 10px; font-weight: 650; letter-spacing: .02em; }
.orca-quick svg { color: currentColor; }

/* ---- back to top ------------------------------------------------------- */
/* Earned much later than the action bar - one and a half screens, by which
   point scrolling back by hand is a real cost. Shown at every width: a long
   page is long on a laptop too. It sits ABOVE the mobile bar rather than
   beside it, so it never competes with the thing it must not compete with. */
.orca-to-top {
  position: fixed; right: var(--gutter); bottom: var(--gutter);
  z-index: 54; width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--ground); color: var(--ink);
  border: 1.5px solid var(--hairline); box-shadow: var(--shadow-md);
  cursor: pointer; opacity: 0; pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
  transform: translateY(8px);
}
.orca-to-top[data-show="true"] { opacity: 1; pointer-events: auto; transform: translateY(0); }
.orca-to-top:hover { color: var(--chrome); border-color: var(--chrome); }

/* ---- the mobile navigation -------------------------------------------- */
/* A full-screen overlay, not a drawer. A drawer has to decide how wide it is
   and then justify the strip of dimmed page beside it; an overlay has one job
   and does it at any screen size. Links are set large and spaced, because the
   thing being tapped is a thumb target rather than a line of text.

   THE CALL TO ACTION STAYS IN THE BAR. It does not go inside the menu. Burying
   the one action the site exists to get behind a tap is the most common and
   most expensive mistake in a mobile header. */
.orca-nav-panel {
  position: fixed; inset: 0; z-index: 60;
  background: var(--dark); color: #fff;
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--loose); padding: var(--gutter);
  /* Not display:none - a menu that is removed from the document cannot be
     transitioned, and it is the transition that tells a reader where the panel
     came from. */
  opacity: 0; visibility: hidden; transition: opacity .22s ease, visibility .22s;
}
.orca-nav-panel[data-open="true"] { opacity: 1; visibility: visible; }
.orca-nav-panel a {
  color: #fff; text-decoration: none; font-size: 31px;
  font-weight: 650; padding: 6px 0;
}
.orca-nav-panel a:hover, .orca-nav-panel a:focus-visible { color: var(--chrome); }
.orca-nav-close {
  position: absolute; top: 14px; right: var(--gutter);
  width: 44px; height: 44px; display: inline-flex;
  align-items: center; justify-content: center;
  background: none; border: 0; color: #fff; cursor: pointer;
}

/* ---- footer ----------------------------------------------------------- */
/* TWO TIERS. An information row, then a quiet legal line.
   The information row exists because of a gap that only appears on a phone:
   the top bar is hidden below 1024px, so without it the hours and the address
   live nowhere on a small screen except the contact panel near the bottom of
   the page. The footer is where people go looking for exactly those two facts,
   and it is the last thing on every page rather than one section of one page.
   Half the section padding: the page has already ended by the time anyone
   reads it. */
.orca-foot {
  background: var(--ground); border-top: 1px solid var(--hairline);
  padding: calc(var(--pad) / 2) var(--gutter);
  font-size: 15px; color: var(--ink-muted);
}
.orca-foot-top { display: flex; gap: var(--block); align-items: flex-start; flex-wrap: wrap; }
.orca-foot-brand { flex: 1 1 240px; min-width: 0; display: flex; flex-direction: column; gap: var(--snug); }
/* LEFT LIKE THE HEADER'S, centered only on a phone where the column is the
   full width (Nick, 30 Aug). Only the LOGO centers on mobile - the blurb and
   the phone stay set left. The template writes the same thing as widget
   settings (align / align_mobile); this is the stylesheet agreeing. */
.orca-foot-brand .orca-logo, .orca-foot-brand .orca-foot-name { text-align: left; }
@media (max-width: 767px) {
  .orca-foot-brand .orca-logo, .orca-foot-brand .orca-foot-name { text-align: center; }
}
.orca-foot-name { font-weight: 800; font-size: 19px; color: var(--brand); letter-spacing: -.01em; }
.orca-foot-blurb { max-width: 34ch; }
/* THE PHONE AND THE HOURS, in the brand column, on every page. Two facts a
   phone reading at 9pm actually wants; the phone number is set at the body
   size and in the ink color rather than muted, because a number you have to
   hunt for is a number nobody rings. */
.orca-foot-reach { display: flex; flex-direction: column; gap: 2px; }
.orca-foot-phone a { color: var(--ink); font-weight: 700; font-size: 17px; }
.orca-foot-hours { color: var(--ink-muted); }
.orca-foot-col { flex: 0 1 auto; display: flex; flex-direction: column; gap: var(--snug); }
.orca-foot-col h3 {
  font-size: 13px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink);
}
.orca-foot-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--tight); }
.orca-foot-col li { display: flex; gap: 10px; align-items: flex-start; }
/* THE SITEMAP OF RECORD SPLITS WHEN TALL. Every main content page is in the
   footer nav (Nick, 30 Aug); past what the rest of the footer is tall, the
   one Pages list breaks into two CSS columns under its one heading. Block
   display, because CSS columns do not apply to a flex container - the gap
   becomes a margin so the rhythm survives the switch. */
.orca-foot-links-2 ul { display: block; columns: 2; column-gap: var(--loose); }
.orca-foot-links-2 li { break-inside: avoid; margin-bottom: var(--tight); }
.orca-foot-col svg { color: var(--chrome); flex: none; margin-top: 2px; }
.orca-foot a { color: inherit; text-decoration: none; }
.orca-foot a:hover { color: var(--brand); text-decoration: underline; }
/* The rule that separates the two tiers is the ONLY line in the footer. Two
   would make it a table. */
.orca-foot-legal-row {
  display: flex; align-items: center; gap: var(--loose); flex-wrap: wrap;
  margin-top: var(--block); padding-top: var(--loose);
  border-top: 1px solid var(--hairline);
  font-size: 14px;
}
.orca-foot-links { display: flex; gap: var(--loose); flex-wrap: wrap; }
.orca-foot-legal { margin-left: auto; }

/* ---- socials ---------------------------------------------------------- */
.orca-socials { display: flex; gap: var(--snug); }
.orca-solo .orca-socials { justify-content: center; }
.orca-group > .orca-lead + .orca-socials { margin-top: var(--loose); }
.orca-socials a {
  width: 44px; height: 44px; border-radius: var(--radius);
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--hairline); color: var(--brand); text-decoration: none;
  background: #fff; box-shadow: var(--shadow-sm);
  transition: box-shadow .18s ease, color .18s ease, border-color .18s ease;
}
.orca-socials a:hover { border-color: var(--accent); color: var(--accent); box-shadow: var(--shadow-md); }

/* ---- containers that paint their own surface -------------------------- */
/* A CARD WITH ITS OWN BACKGROUND OR BORDER NEVER TOUCHES THE SCREEN EDGE ON
   MOBILE OR TABLET. A BAND ALWAYS DOES.

   The distinction is whether the container is an OBJECT ON a surface or a
   surface in its OWN RIGHT:

   .orca-self-surface - a card. It is meant to be seen sitting on the page, so it
     needs the page on both sides of it. A card bleeding off both edges of a
     phone stops reading as a card and reads as the page changing color, so
     the thing it was there to distinguish stops being distinguished.

   .orca-full-bleed - a band. Edge to edge is the point at every width. When the duo
     stacks on a phone, each half becomes its own full-width band - a gutter
     there would make it look like a card that had failed to be one.

   Anything inside .orca-inner already has the page gutter and needs neither mark.
   Every painted container OUTSIDE .orca-inner must carry one or the other, so the
   choice is recorded rather than defaulted - see assertSelfSurface. */
@media (max-width: 1024px) {
  /* TWO COLUMNS ON A TABLET (Nick, 27 Aug): four across is unreadable at
     tablet widths, one across wastes them. Same tail re-decision as the 900px
     block above: the desktop tail no longer describes this row. */
  .orca-cards { --cards-track: 4; }
  .orca-cards > * { grid-column-start: auto; }
  .orca-cards-center-tail.orca-cards-odd > *:last-child { grid-column-start: 2; }
  .orca-self-surface {
    margin-inline: var(--gutter);
    width: auto;
    border-radius: var(--radius);
    overflow: hidden;
  }
}

/* ---- the phone -------------------------------------------------------- */
/* ONE COLUMN OF CARDS ON A PHONE (Nick, 28 Aug: "mobile cards layout should be
   1 col: cards with images do not count as an image gallery").

   The two-up rule that photo grids get is about PHOTOGRAPHS: a set of pictures
   read as a set, where one per screen turns nine images into nine statements.
   A card is a picture WITH WORDS UNDER IT, and at 187px those words are two
   syllables a line - which is what shipped, because until now the card grid
   had no phone rule at all in this stylesheet.

   THIS BLOCK IS HERE AND NOT IN elementorBridge(). The bridge is deliberately
   never sent (see buildDesignCss), so the phone rule written into it had never
   applied to anything: the tablet rule above ran all the way down to zero. A
   rule in a function nothing calls is a rule that does not exist. */
@media (max-width: 767px) {
  .orca-cards { --cards-track: 2; }
  /* One column has no short last row, so nothing is centered and nothing is
     offset: every card starts where its own row starts. */
  .orca-cards > * { grid-column-start: auto; }
  /* AND A COMPACT CARD STANDS BACK UP. Compact exists to rescue a torn second
     row; one column has no second row, so the reason for it is gone - and a
     third of a phone is an 80px thumbnail beside 22 characters a line. */
  .orca-cards-compact .orca-card { display: flex !important; flex-direction: column; min-height: 0; }
  .orca-cards-compact .orca-card > *:first-child { position: static; }
  .orca-cards-compact .orca-card img {
    position: static; width: 100%; height: auto;
    aspect-ratio: 1.0000;
  }
}

/* A band is full width; its CONTENT still sits in the page's grid. */
.orca-full-bleed { width: 100%; }

/* ---- the figures band -------------------------------------------------- */
/* EVIDENCE, not mood. Business gets this where the other two get the duo.

   A supplier's page is an argument, and the strongest thing on one is usually a
   number somebody can check. Years in business beats "established and trusted";
   "3,400 lines held" beats "extensive range".

   No card boxes. Boxes would make this a card row, which the section above it
   already is, and the numbers are the object here - a border around each one
   just puts a fence between them. Hairlines between the columns instead, which
   is what a table of figures has always done.

   EVERY FIGURE CARRIES ITS SOURCE. See assertFigures: a number Orca invented
   would be the most damaging thing this system could emit, because it is the
   part a reader is most likely to believe and least able to check. */
/* THE COLUMN RULE IS THE COMPONENT. It is what makes four numerals a table of
   figures rather than four numerals, so it survives every breakpoint - it is
   not a desktop flourish that gets dropped when the row wraps. */
.orca-figures { display: flex; }
.orca-figure {
  flex: 1 1 0; min-width: 0; padding: 0 var(--loose);
  display: flex; flex-direction: column; gap: var(--tight);
  border-left: 1px solid var(--hairline);
}
.orca-figure:first-child { border-left: 0; padding-left: 0; }
.orca-figure:last-child { padding-right: 0; }

/* Tablet: still one row, but the columns stop being equal thirds and take the
   width their contents need, spaced apart. Equal columns at this width leave a
   two-character figure floating in the middle of a wide empty box. */
@media (max-width: 1024px) {
  .orca-figures { justify-content: space-around; flex-wrap: wrap; row-gap: var(--loose); }
  .orca-figure { flex: 0 1 auto; padding: 0 var(--loose); }
  .orca-figure:first-child { padding-left: var(--loose); }
  .orca-figure:last-child { padding-right: var(--loose); }
}
/* BOTH SPELLINGS. The preview writes b/span/small; the TEMPLATE emits
   .orca-fig-value (an h3), .orca-fig-label and .orca-fig-source -- and only the preview's
   tags were styled, so every BUILT figures band drew its numbers as
   ordinary h3s (found on the old build, 2 Sep; same bug here). */
.orca-figure b, .orca-figure .orca-fig-value, .orca-figure .orca-fig-value h3 {
  font-size: clamp(38px, 4.6vw, 44px);
  font-weight: 800; line-height: 1; letter-spacing: -.03em;
  color: var(--brand); font-variant-numeric: tabular-nums;
  margin: 0;
}
.orca-figure span, .orca-figure .orca-fig-label { font-size: 17px; font-weight: 600; }
.orca-figure small, .orca-figure .orca-fig-source { font-size: 14px; color: var(--ink-muted); }

/* ---- the duo band ----------------------------------------------------- */
/* Half a square photograph, half a color block carrying copy. Edge to edge on
   desktop, no page gutter: the point is the hard vertical seam down the
   middle. Inset below 1024px by the rule above. */
.orca-duo { display: flex; width: 100%; align-items: stretch; }
.orca-duo > * { flex: 1 1 50%; min-width: 0; }
/* The ratio governs a BOX; the photograph fills it. Capped in viewport height
   as well, because half of a very wide window is a very large picture however
   sensible the ratio. */
.orca-duo-media { aspect-ratio: 1.0000; max-height: 64vh; }
/* NO .orca-duo-photo RULE ANY MORE. The photograph is the media container's OWN
   background (Nick's hand-built band, 30 Aug) - an <img> child had an
   intrinsic height to argue with stretch, and the seam stopped short of the
   block. The template writes cover/center as settings; the preview draws the
   same thing inline. A rule for a class no template emits is the invisible
   failure prefixed() warns about, so it is gone rather than kept "just in
   case". */
.orca-duo-media { background-size: cover; background-position: center center; }
.orca-duo-block {
  /* CENTERED IN BOTH AXES (Nick, 30 Aug). The duo is a poster half, not a
     reading column: its few lines sit in the middle of the color block. */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: var(--pad) clamp(28px, 4vw, 72px);
  /* Not accent. A half-page of saturated color beside a photograph is two
     things shouting; this lets the photograph carry the section and saves the
     accent for the call to action immediately below it. */
  background: var(--dark); color: var(--reversed);
}
.orca-duo-block .orca-eyebrow { color: var(--accent); }
.orca-duo-block p, .orca-duo-block li { color: rgba(255,255,255,.86); }
.orca-duo-block svg { color: var(--accent); }
.orca-duo-block .orca-btn-out { color: #fff; border-color: #fff; }
.orca-duo-block .orca-btn-out:hover { background: #fff; color: var(--dark); }
.orca-duo-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--snug); }
.orca-duo-list li { display: flex; gap: var(--snug); align-items: center; font-size: 17px; }
.orca-panel .orca-duo-list svg { color: var(--accent); }
.orca-duo-list svg { flex: none; }

/* THE BLOCK'S GROUND IS A SURFACE (Nick, 2 Sep). Classless keeps the
   system's own default above; a tone class from the template overrides it,
   so the engine or the document can vary the half without a new template. */
.orca-duo-block.orca-on-dark { background: var(--dark); color: var(--reversed); }
.orca-duo-block.orca-on-dark .orca-eyebrow { color: var(--accent); }
.orca-duo-block.orca-on-dark p, .orca-duo-block.orca-on-dark li { color: rgba(255,255,255,.86); }
.orca-duo-block.orca-on-dark svg { color: var(--accent); }
.orca-duo-block.orca-on-dark .orca-btn-out { color: #fff; border-color: #fff; }
.orca-duo-block.orca-on-dark .orca-btn-out:hover { background: #fff; color: var(--dark); }
.orca-duo-block.orca-on-recessed { background: var(--recessed); color: var(--ink); }
.orca-duo-block.orca-on-recessed .orca-eyebrow { color: var(--brand); }
.orca-duo-block.orca-on-recessed svg { color: var(--accent); }
.orca-duo-block.orca-on-ground { background: var(--ground); color: var(--ink); }
.orca-duo-block.orca-on-ground .orca-eyebrow { color: var(--brand); }
.orca-duo-block.orca-on-ground svg { color: var(--accent); }

/* ---- centering --------------------------------------------------------- */
/* A block centers when it is ALONE IN ITS ROW - a hero, a full-width call to
   action. Beside a photograph it is a column, and a centered column next to an
   image reads as a mistake rather than a decision. So this is a property of
   the row, never of the system. */
.orca-solo .orca-group { align-items: center; text-align: center; }
.orca-solo .orca-group p { margin-inline: auto; }
.orca-solo .orca-group .orca-btns { justify-content: center; }
/* Everything in a two-up row stays left, at every width above mobile - EXCEPT
   the duo, whose block half is a poster and centers (Nick, 30 Aug). */
.orca-feature .orca-group { align-items: flex-start; text-align: left; }
.orca-feature .orca-group p { margin-inline: 0; }
.orca-duo-block .orca-group { align-items: center; text-align: center; }
.orca-duo-block .orca-group p { margin-inline: auto; }
/* AND ONLY ONE RULE SAYS SO. The flex-start line below used to name the
   duo's button row as well, one line under the centring rule - equal
   specificity, later in the file, so it won and the duo's single button hung
   at the block's left edge through two rounds of "fixed" ("orca-btns class
   on duo row needs justify-content: center" - Nick, 30 Aug). The element
   setting (buttons() extra in duo.orca-ts) and this rule now agree, nothing
   contradicts them, and steps-check counts the mentions. */
.orca-duo-block .orca-btns { justify-content: center; }
.orca-feature .orca-btns { justify-content: flex-start; }

/* ---- the raised panel ------------------------------------------------- */
/* A block of GROUND color lifted off a tinted surface. The inverse of a
   Recessed section: instead of pushing a band back, it brings one block
   forward, which is a cheap and durable way to say "this bit matters" without
   color, a border or a heading two sizes up.
   
   ONE RULE, and it is absolute: a panel only works ON a non-Ground surface.
   Ground on Ground is invisible and the shadow becomes a smudge round nothing.
   So a panel implies a Recessed, Statement or Photographic section behind it. */
.orca-panel {
  background: var(--ground); border-radius: var(--radius);
  padding: clamp(28px, 4vw, 56px);
  box-shadow: var(--shadow-md);
}
/* On a photograph it needs to be opaque and slightly tighter. */
.orca-photo .orca-panel { max-width: 640px; }
/* A panel wrapping a map has no padding on the map side - the map runs to the
   panel's edge and the radius clips it. Padding lives on the text side only. */
.orca-panel.orca-flush { padding: 0; overflow: hidden; }
/* 5% AT EVERY SIZE (Nick, 2 Sep): percentage padding tracks the panel's own
   width, so the body breathes proportionally on a phone and a monitor alike
   -- the clamp gave a phone 28px on a 350px card, which crowded it. */
.orca-panel.orca-flush .orca-panel-body { padding: 5%; }

/* ---- the contact panel ------------------------------------------------ */
/* Full container width. It reads as a closing object because it is a raised
   panel on a tinted surface, not because it is narrower than the section above
   it - and at 75% the map column was too thin to be a map. */
.orca-contact-panel { width: 100%; }
/* PADDING IS NEVER ZERO WHERE THE BACKGROUND CHANGES.

   A color change cannot do the job of spacing. Where a section's surface
   differs from its neighbor's, content jammed against the seam reads as a
   mistake however deliberate it was, and the eye has nowhere to rest between
   two different grounds.

   Zero padding is legal in exactly two places, both decided by mayCollapseTop
   below and nowhere else:

     1. Between two sections on the SAME surface, which are meant to read as
        one continuous block.
     2. Where the section's content is an inset panel with its own padding and
        its own shadow. The panel holds the content off the seam, so the
        section padding is adding height and nothing else. Per-system, because
        whether the seam survives it depends on how loud the seam is:
        contactFlush in design-systems.orca-ts.

   Everywhere else the generator refuses to emit it. */
/* THE WIDTHS ARE SETTINGS: 30% map, 70% detail, straight from Nick's third
   export (2 Sep). His first export said 48/48 — but the page he approved
   never rendered that way, because an old flex-basis here was silently
   pinning the map to a third, and honoring the 48 "faithfully" crushed the
   facts column until the phone number ran three lines ("this is not what i
   sent"). His rewrite puts the ratio he means in the widths themselves, so
   the stylesheet's whole job is to NOT fight them: no basis, and the body
   grows into any slack. Stacking (tablet column, phone column-reverse) is
   settings too. */
.orca-contact-split { display: flex; align-items: stretch; }
.orca-contact-split .orca-map { flex: none; }
.orca-contact-split .orca-panel-body { flex: 1 1 auto; min-width: 0; }

/* ---- the contact card BESIDE the form --------------------------------- */
/* ONE ROW ON A LARGE SCREEN: the card on the left, the form on the right.
   Direction and widths are container settings (row on desktop, the whole
   thing column-REVERSE on tablet and phone so the form leads) - the template
   is the record; this only seats the form's group level with the card. */
.orca-contact-row { display: flex; }
.orca-contact-form-col .orca-group { margin-top: 0; }

/* ---- map -------------------------------------------------------------- */
/* Fills the panel's full height rather than declaring one of its own, so the
   detail side decides how tall the card is. */
.orca-map { position: relative; min-height: 100%; background: var(--recessed); }
.orca-map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
/* No address: the third becomes a photograph rather than an empty column or a
   map of somewhere the client does not do business at. Decorative by definition -
   it carries no information, so it carries no alt text either. */
.orca-map-photo { background-size: cover; background-position: center; }

/* ---- icon cards -------------------------------------------------------- */
/* A LIST THAT IS ALONE IN ITS SECTION BECOMES CARDS.

   A list is measure-constrained - it has to be, or the lines get too long to
   read - so a bare list in a full-width section occupies about 55 characters
   of a 1200px row and leaves the other two thirds empty. That reads as a
   section that failed to load rather than one that was composed.

   Cards take the width they have been given. Three across turns the same three
   facts from a narrow column into a row that fills its section, and the icons
   stop being bullets and start being the thing the eye lands on.

   The rule is about the section, not the list: a list BESIDE something - the
   duo band's photograph, the contact panel's map - is already sharing its row
   and stays a list. */
.orca-icon-cards { display: flex; gap: var(--snug); }
.orca-icon-card {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: var(--tight);
  padding: var(--loose);
  background: var(--ground); border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
/* THE ICON IS THE POINT OF THE CARD, so it is sized like one.
   At 26px it was a bullet that had wandered up from the list it replaced; a
   card whose picture is smaller than its heading has not really become a card.
   Thinner stroke at this size - 1.6px on a 48px glyph reads as heavy. */
.orca-icon-card svg { color: var(--accent); width: 48px; height: 48px; stroke-width: 1.35; }
.orca-icon-card b { font-size: 18px; font-weight: 650; }
.orca-icon-card span { font-size: 16px; color: var(--ink-muted); }
.orca-icon-card > svg + b { margin-top: var(--snug); }

/* ---- detail list ------------------------------------------------------ */
/* TIGHT (Nick, 2 Sep): three short facts in half a panel do not need air
   between them - the ringed icons already give every row its height. */
/* DIVS, NOT A LIST (Nick, 2 Sep: "take contact details out of UL. i do not
   like the indent"). A UL invites the theme's and the editor's own list
   rules — the indent came from one of them, not from here — so the rows are
   plain divs the template marks with .orca-fact, and nothing else has opinions
   about them. */
.orca-details { margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--tight); }
/* CENTERED ON THE RING - except the address, which runs two lines: its ring
   sits with the street line, not floating between street and city. The
   template marks the multi-line item; one-line rows stay centered. */
.orca-details .orca-fact { display: flex; gap: var(--snug); align-items: center; }
.orca-details .orca-fact.orca-two-line { align-items: flex-start; }
/* The text column may shrink, and a word longer than the line may break: a
   long email on a phone truncated before this ("catering@frbbq.orca-co..." on the
   375px build, 2 Sep). break-word, NOT anywhere — anywhere splits words that
   would have fit ("2220 Acade my Pl" on the desktop build, same day). */
.orca-details .orca-fact > div { min-width: 0; overflow-wrap: break-word; }
.orca-details svg { color: var(--accent); flex: none; }
.orca-details b { display: block; font-size: 17px; font-weight: 650; }
.orca-details span { font-size: 15px; color: var(--ink-muted); }
.orca-details a { color: inherit; text-decoration: none; }
.orca-details a:hover { text-decoration: underline; }

/* THE RINGED ICON (Nick's contact redesign, 2 Sep): the fact's mark in a
   thin accent circle, the value bold beside it, the note under the value. */
.orca-ico {
  flex: none; width: 40px; height: 40px; border: 2px solid var(--accent);
  border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; color: var(--accent);
}
.orca-ico svg { width: 17px; height: 17px; }

/* TWO COLUMNS when the hours were asked for: the reachable facts and the
   button left, the hours as their own block right. */
.orca-contact-cols { display: flex; gap: clamp(28px, 3.5vw, 56px); align-items: flex-start; width: 100%; }
.orca-contact-cols > * { flex: 1 1 0; min-width: 0; }
/* INSIDE THE PAIRED CARD the columns are half of 60% of a row, and the
   clamp's desktop gap (up to 56px) was exactly the room the email needed to
   stay on one line ("why is email brokenline" — Nick, 2 Sep). The card
   keeps the clamp's floor and gives the difference back to the words. */
.orca-contact-card-col .orca-contact-cols { gap: 28px; }
.orca-hours-head { display: flex; gap: var(--snug); align-items: center; margin-bottom: 8px; }
.orca-hours-head h3 { margin: 0; font-size: 18px; }
@media (max-width: 700px) { .orca-contact-cols { flex-direction: column; } }
.orca-group > .orca-details + .orca-btns { margin-top: var(--loose); }

/* ---- tables ------------------------------------------------------------- */
/* HOUSE RULE (Nick, 27 Aug): tables carry NO background and NO border rules
   — not ours, not the theme's zebra fills, not WordPress's cell boxes — with
   ONE exception: a 1px solid horizontal separator between rows. Typography
   is free (the hours table keeps its small caps below); paint is not.
   !important on purpose: this rule exists to beat whoever painted the cells,
   which is exactly the fight Nick's hand CSS on the live hours table had to
   win with the same weapon. */
.orca-section table, .orca-section thead, .orca-section tbody, .orca-section tr,
.orca-section th, .orca-section td { background: none !important; border: 0 !important; }
.orca-section table { border-collapse: collapse; }
.orca-section tr + tr { border-top: 1px solid var(--hairline) !important; }

/* ---- opening hours ------------------------------------------------------ */
/* A TABLE, in small caps of the body font. Seven bolded "Monday: 11:00 AM"
   lines read as seven facts; two quiet columns read as one. Built by
   templates/contact.orca-ts from the details siteFacts marks with the clock.
   Typography only — the paint rules above are the whole of what a table may
   draw. */
.orca-hours { font-variant-caps: all-small-caps;
  letter-spacing: .05em; color: var(--ink-muted); font-size: .95em; }
.orca-hours th { text-align: left; font-weight: 600; padding: 3px 20px 3px 0;
  color: var(--ink); white-space: nowrap; }
.orca-hours td { padding: 3px 0; }
.orca-group > .orca-hours + .orca-btns { margin-top: var(--loose); }
.orca-group > h2 + .orca-details { margin-top: var(--snug); }

/* Nothing else gets a shadow. Buttons stay flat: a raised button is a 2014
   idiom and the fill already says it is pressable. Full-width bands stay flat
   because a band is the page, not an object on it - shadowing one implies it
   floats over something, and there is nothing behind it. */

/* ---- accent call to action -------------------------------------------- */
/* Directly beneath the duo. The tint sets it up, the accent closes it. */
.orca-accent-cta { background: var(--accent); color: var(--reversed); }
.orca-accent-cta p { color: rgba(255,255,255,.9); }
.orca-accent-cta .orca-btn { background: #fff; color: var(--accent); border-color: #fff; }
.orca-accent-cta .orca-btn-out { background: transparent; color: #fff; border-color: rgba(255,255,255,.75); }

/* ---- the store ---------------------------------------------------------- */
/* WooCommerce draws the store's markup, not us, so every .elementor-kit-834 here aims
   at Woo's own classes and is left unprefixed by FOREIGN below - a prefixed
   copy would style markup nothing renders, the invisible miss this file
   keeps having to relearn. The funnel contract stands: Woo's LAYOUT inside
   a checkout is not redrawn - but the kit's colors, corners and type DO
   reach in ("we need rules to override the elementor/woocommerce default
   css link colors, fonts etc" - Nick, 3 Sep, looking at default-blue links
   and a fallback serif on the cart). */

/* THE GRID, NOT WOO'S FLOATS. Woo lays the shop out with percentage floats
   and a clearfix, which is why the cards never lined up with anything else
   on the site. A grid makes them equal height and hands the gap to one
   value. auto-fill rather than Woo's columns-N: the count is a consequence
   of the measure, so the same rule is right on the wide shop band and in
   the related strip. */
.woocommerce ul.products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: clamp(20px, 2.5vw, 32px);
  margin: 0; padding: 0; list-style: none;
}
.woocommerce ul.products::before,
.woocommerce ul.products::after { display: none; }

/* THE CARD, in the system's card idiom - white on hairline with the small
   lift - at the store's own 8px corner: a product card is a thing you pick
   up; the rest of the site is a page you read. This is also where a client
   who wants a 30px radius gets it - a product-card decision, not a
   whole-system one. */
.woocommerce ul.products li.product {
  width: auto; float: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; position: relative;
  background: #fff; border: 1px solid var(--hairline);
  border-radius: 8px; overflow: hidden; box-shadow: var(--shadow-sm);
  transition: box-shadow .18s ease, transform .18s ease;
}
/* A product card IS a link, so it earns the hover a.orca-card already has: the
   lift plus the accent edge. */
.woocommerce ul.products li.product:hover {
  box-shadow: var(--shadow-md); transform: translateY(-2px);
  border-color: var(--accent);
}

/* SQUARE, EDGE TO EDGE. Catalog shots arrive in every shape, and the grid
   only reads as a set when every object sits in the same frame. The card's
   overflow crops the corners. */
.woocommerce ul.products li.product img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover; display: block;
  margin: 0; border-radius: 0;
}

/* The words wear the card's padding; the picture does not. The link wrapper
   takes the slack, so the buy button sits on the card's floor whatever the
   length of the name above it. */
.woocommerce ul.products li.product > .woocommerce-LoopProduct-link {
  flex: 1 1 auto; display: flex; flex-direction: column;
  color: var(--ink); text-decoration: none;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title {
  padding: var(--snug) var(--snug) 0; margin: 0;
  font-size: 23px; line-height: 1.3; font-weight: 650; color: var(--ink);
}
.woocommerce ul.products li.product .price {
  padding: 6px var(--snug) 0; margin: 0;
  color: var(--ink-muted); font-size: .95em;
  font-variant-numeric: tabular-nums;
}
.woocommerce ul.products li.product .price ins {
  text-decoration: none; color: var(--ink); font-weight: 650;
}
.woocommerce ul.products li.product .price del { opacity: .6; margin-right: 6px; }
.woocommerce ul.products li.product .button {
  margin: var(--tight) var(--snug) var(--snug); align-self: flex-start;
}

/* The sale flash: the accent, quietly, and none of Woo's green circle. */
.woocommerce span.onsale {
  position: absolute; top: 10px; left: 10px; z-index: 1;
  min-height: 0; min-width: 0; margin: 0; padding: 2px 12px;
  border-radius: 999px; line-height: 1.7;
  background: var(--accent); color: var(--on-accent);
  font-size: 12px; font-weight: 650; letter-spacing: .02em;
}

/* ADD TO CART IS THE PRIMARY BUTTON EVERYWHERE IT APPEARS, AND NOTHING ELSE ON
   A PRODUCT PAGE MAY USE THE PRIMARY TREATMENT. A product page with two
   primary buttons has no primary button. */
.woocommerce .single_add_to_cart_button,
.woocommerce ul.products li.product .add_to_cart_button {
  background: var(--chrome); color: var(--reversed); border: 1.5px solid var(--chrome);
  border-radius: var(--radius); padding: 8px 32px; font-weight: 650;
}
.woocommerce div.product .button:not(.single_add_to_cart_button):not(.add_to_cart_button),
.woocommerce div.product a.button.orca-alt:not(.single_add_to_cart_button) {
  background: transparent; color: var(--ink); border: 1.5px solid var(--hairline);
}

/* Above the grid: the count is a whisper, the ordering control is a field. */
.woocommerce .woocommerce-result-count { margin: 0 0 var(--snug); color: var(--ink-muted); font-size: .9em; }
.woocommerce .woocommerce-ordering { margin: 0 0 var(--snug); }

/* EVERY WOO FIELD, ONE TREATMENT - the ordering select, the quantity, the
   coupon box, the checkout's own inputs. Left alone they inherit the
   theme's controls, which is where the 2012 came from. */
.woocommerce select,
.woocommerce .input-text,
.woocommerce .qty {
  font: inherit; color: var(--ink); background: #fff;
  border: 1px solid var(--hairline); border-radius: var(--radius);
  padding: 8px 12px;
}
.woocommerce .qty { width: 76px; text-align: center; }
.woocommerce select:focus,
.woocommerce .input-text:focus,
.woocommerce .qty:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---- the single product page (drawn by our theme-builder template) ------ */

/* The name is the H1, but not the HERO h1: the interior scale's biggest
   step. The hero clamp would shout a product's name across half the screen. */
.woocommerce div.product .product_title {
  margin: 0; font-size: clamp(26px, 3.4vw, 41px);
}
.woocommerce div.product p.price {
  margin: 0; color: var(--ink); font-weight: 650;
  font-size: 23px; font-variant-numeric: tabular-nums;
}
.woocommerce div.product p.price del { opacity: .55; font-weight: 400; margin-right: 8px; }
.woocommerce div.product p.price ins { text-decoration: none; }
.woocommerce div.product .woocommerce-product-gallery img { border-radius: 8px; }
.woocommerce div.product .stock { margin: 0; color: var(--ink-muted); }

/* The buy form: quantity beside the button, both on one baseline. */
.woocommerce div.product form.cart { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 0; }
.woocommerce div.product form.cart.variations_form { display: block; }
.woocommerce div.product form.cart .woocommerce-variation-add-to-cart { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.woocommerce div.product form.cart table.variations { margin: 0 0 var(--snug); }
.woocommerce div.product form.cart table.variations th,
.woocommerce div.product form.cart table.variations td { border: 0; padding: 4px 12px 4px 0; vertical-align: middle; }
.woocommerce div.product form.cart table.variations label { margin: 0; font-weight: 600; color: var(--ink); }
.woocommerce div.product .reset_variations { color: var(--ink-muted); font-size: .85em; }

/* The fine print under the button: category, SKU. A colophon, not copy. */
.woocommerce div.product .product_meta {
  display: flex; flex-direction: column; gap: 2px;
  margin: var(--tight) 0 0; padding-top: var(--snug);
  border-top: 1px solid var(--hairline);
  color: var(--ink-muted); font-size: .9em;
}

/* Woo prints its own "Related products" h2 inside our recessed band. */
.orca-product-related section.related > h2 { margin: 0 0 var(--loose); }

/* ---- Woo speaks the kit's colors ---------------------------------------- */
/* THE CART PAGE WAS BLUE (Nick, 11 Sep). WooCommerce's own pages - cart,
   checkout, account - are drawn by Woo, not by Orca's widgets, so every
   control on them wore Elementor's factory defaults: sky-blue buttons and
   links on a page whose palette says rust and leather. The kit styles what
   the kit renders; THIS block is the treaty with what Woo renders. Actions
   take the accent - the same solid the site's own buttons wear - and links
   inside Woo's tables and notices take it too. !important on the button
   colors, deliberately: Woo and the kit's globals both bid for these and
   the palette must win unconditionally, same argument as the header's
   state colors. */
.woocommerce a.button, .woocommerce button.button, .woocommerce input.button,
.woocommerce a.button.orca-alt, .woocommerce button.button.orca-alt, .woocommerce input.button.orca-alt,
.woocommerce .checkout-button, .woocommerce #payment #place_order,
.woocommerce #respond input#submit,
.wc-block-components-button:not(.is-link) {
  background: var(--accent) !important;
  color: var(--on-accent, #fff) !important;
  border: 2px solid var(--accent) !important;
  border-radius: var(--radius);
  font-weight: 650;
}
.woocommerce a.button:hover, .woocommerce button.button:hover,
.woocommerce input.button:hover, .woocommerce .checkout-button:hover,
.woocommerce #payment #place_order:hover,
.wc-block-components-button:not(.is-link):hover {
  filter: brightness(1.07);
  color: var(--on-accent, #fff) !important;
}
.woocommerce button.button:disabled, .woocommerce button.button:disabled[disabled] {
  background: var(--accent) !important;
  color: var(--on-accent, #fff) !important;
  opacity: .55;
}

/* The links Woo draws: the cart's product names, the notices' actions, the
   account pages' navigation. Scoped to Woo's own containers so the site's
   header and footer - which also live on body.woocommerce-page - keep the
   kit's own treatment. */
.woocommerce table.shop_table a:not(.button),
.woocommerce-message a:not(.button), .woocommerce-info a:not(.button),
.woocommerce-error a:not(.button),
.woocommerce-MyAccount-navigation a, .woocommerce-MyAccount-content a:not(.button),
.wc-block-components-totals-coupon-link {
  color: var(--accent) !important;
}

/* The notice stripe was Woo's blue too. */
.woocommerce-message, .woocommerce-info { border-top-color: var(--accent); }
.woocommerce-message::before { color: var(--accent); }
.woocommerce-info::before { color: var(--brand); }

/* ---- the category circles (Nick's Target reference, 9 Sep) -------------- */
/* THE SIZE IS THE COLUMN'S, NEVER THE WIDGET'S ("the image should have no
   set height/width. instead, just set the aspect ratio to 1/1 and object
   fit to cover. the column # option in the listing/loop widget itself
   takes care of the rest" - Nick, 10 Sep). The card template sets no
   width or height; the image fills whatever column the carousel deals it,
   and the ratio keeps it square at any count. The stylesheet also
   contributes the hover, because a card is a link and a link answers the
   cursor. NOTHING GROWS UNDER THE CURSOR - the circle lifts like every
   other link. */
.orca-commerce-categories .orca-ccard-img img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  transition: box-shadow .18s ease; border-radius: 50%;
}
.orca-commerce-categories .orca-ccard:hover .orca-ccard-img img { box-shadow: var(--shadow-md); }

/* THE MOMENT BEFORE SWIPER. Until the script initializes, a slide is an
   unstyled full-width block - and with the image now sized by its column
   (above), the first paint showed ONE VIEWPORT-WIDE CIRCLE where the rail
   would be ("why does the category slide load like this at first?" -
   Nick, 11 Sep; before 10 Sep the fixed 170px hid the same flash). So the
   uninitialized state is a SKELETON OF THE FINISHED RAIL: a clipped flex
   row of slides at roughly their final width. Swiper adds its
   -initialized class and takes over; with JavaScript off this row IS the
   rail, which is a better no-script shop than a one-circle page. */
.orca-commerce-categories .swiper:not(.swiper-initialized) .swiper-wrapper,
.orca-commerce-categories .swiper-container:not(.swiper-container-initialized) .swiper-wrapper {
  display: flex; gap: var(--snug); overflow: hidden;
}
.orca-commerce-categories .swiper:not(.swiper-initialized) .swiper-slide,
.orca-commerce-categories .swiper-container:not(.swiper-container-initialized) .swiper-slide {
  flex: 0 0 auto; width: clamp(120px, 12vw, 190px);
}

/* ---- the featured feature column (Nick's mapping, 11 Sep) --------------- */
/* "column 1: featured photograph background, section title and body text
   with button overlay. scrim" - the hero's own gradient numbers, so the
   words sit on the same darkness everywhere words sit on photographs. */
.orca-featured-scrim { position: relative; }
.orca-featured-scrim::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.65) 0%, rgba(0,0,0,.30) 45%, rgba(0,0,0,0) 80%);
  pointer-events: none;
}
.orca-featured-scrim > * { position: relative; z-index: 1; }
.orca-featured-scrim, .orca-featured-scrim p { color: #fff; }

/* ---- the featured tile (his "ecom home" export, 10 Sep) ----------------- */
/* The wash is a gradient, not the export's flat 0.73 overlay that nearly
   erased the product photograph: solid brand behind the words, thinning
   toward the edges so the product still reads. Clipped by the tile's own
   radius via its overflow. */
.orca-featured-tile { position: relative; }
.orca-featured-tile::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse at center,
    var(--brand) 0%,
    color-mix(in srgb, var(--brand) 62%, transparent) 58%,
    color-mix(in srgb, var(--brand) 34%, transparent) 100%);
}
.orca-featured-tile > * { position: relative; z-index: 1; }
/* THE WHOLE TILE IS THE DOOR: the button's own anchor stretches over the
   tile - one anchor covering everything, never an anchor nested in an
   anchor - and hovering anywhere on the tile answers with the button's
   own style swap. */
.orca-featured-tile .elementor-widget-button a::after { content: ''; position: absolute; inset: 0; }

/* ---- the store header's search pill (his commerce header, 9 Sep) -------- */
/* The pill's look - radius, shadow, icon - rides in the widget's own
   settings; the stylesheet contributes the behavior his export wrote as
   pasted CSS: the pill WIDENS WHILE IT IS HELD. Focus, not hover, so the
   nothing-grows-under-the-cursor rule stands. The importants are earned:
   Elementor writes the container's width under the template id and the
   element id - three classes - and his export paid the same toll. */
.orca-site-header .orca-searcher { transition: width .25s ease; }
/* ON A LAPTOP the pill is a fixed 17vw that grows while held. BELOW the
   nav breakpoint the vw widths that look right on a wide screen collapse
   to a sliver ("search bar gets weird at responsive widths" - Nick,
   9 Sep), so the pill stops being a vw at all: it flexes into whatever
   room the bar has between the brand and the collapsed nav, banded so it
   is never a sliver and never a runway, and the focus growth stands down
   - a flexing pill is already as wide as the bar allows. */
@media (min-width: 1025px) {
  .orca-site-header .orca-searcher:focus-within { width: 26vw !important; }
}
/* BELOW THE NAV BREAKPOINT the desktop percentages stop describing
   anything real - the nav is a burger, not a 39% row - so every column
   goes to its own width and the pill flexes into the spare room. The
   importants are matched force against Elementor's element-level widths.
   flex-shrink 0 on the two marks: the account door was the softest thing
   in the cluster and the squeeze crushed it to nothing. */
@media (max-width: 1024px) {
  .orca-site-header .orca-brand { width: auto !important; flex: 0 1 auto; }
  .orca-site-header .orca-nav { width: auto !important; flex: 0 0 auto; }
  .orca-site-header .orca-header-right { width: auto !important; flex: 0 0 auto; }
  .orca-site-header .orca-account-slot, .orca-site-header .orca-cart-slot { flex-shrink: 0; }
  .orca-site-header .orca-searcher {
    width: auto !important;
    flex: 1 1 auto;
    min-width: 130px; max-width: 340px;
    padding: 0 12px !important;
  }
}
/* ON A PHONE the bar is two rows: brand, burger, account and cart on the
   first; the search pill on its own full-width line under them - a pill
   squeezed between a wordmark and three controls at 375px was pushing
   the whole cluster off the edge. The bar's fixed height gives way so
   the second row has somewhere to be. The cart toggle also sheds its
   subtotal: the bag and its count say enough. */
@media (max-width: 767px) {
  /* Scoped to a bar that HAS a search pill: a non-store header keeps its
     one-row compact height exactly as before. */
  .orca-site-header:has(.orca-searcher) { height: auto; min-height: var(--header-h-compact); }
  .orca-site-header:has(.orca-searcher) > .orca-inner { flex-wrap: wrap !important; }
  /* The wordmark yields: at 375px a full-width logo left no room for the
     burger, the account door and the cart on the first row. */
  .orca-site-header:has(.orca-searcher) .orca-logo img { max-width: 38vw; }
  .orca-site-header .orca-searcher {
    order: 9;
    flex-basis: 100%; max-width: none;
    padding: 0 0 10px !important;
  }
  .orca-site-header .orca-cart-slot .elementor-menu-cart__toggle_button .elementor-button-text { display: none; }
}
/* The live-results dropdown floats over the page, never pushes the bar. */
.orca-site-header .orca-searcher .e-search-results-container { z-index: 30; }
/* THE QUIET MARKS STATE THEIR GROUND. The account door and the cart toggle
   are icons, not pills - but a site can carry stray button paint (Open
   Range's old orc- prototype snippet forces every .elementor-button gold,
   pill-shaped and padded, all with !important). The important here is
   matched force, and with it the fight comes down to specificity, where
   three classes beat one. Scoped to the two header marks and nothing else. */
.orca-site-header .orca-account-slot .elementor-button,
.orca-site-header .orca-cart-slot .elementor-menu-cart__toggle_button {
  background: transparent !important;
  /* BORDER 0, FOREVER (Nick, 11 Sep): Elementor's menu-cart toggle ships
     its own border and the kit's button styling offers another; a quiet
     mark wears neither. This rule already stripped the fill, the radius
     and the shadow - the border was the one paint it forgot. */
  border: 0 !important;
  border-radius: 0 !important;
  padding: 4px 6px !important;
  box-shadow: none !important;
}

/* ---- the cart and totals tables ----------------------------------------- */
/* Hairlines between rows, nothing boxed: Woo borders every cell, which
   reads as a spreadsheet sitting in the page. */
.woocommerce table.shop_table {
  border: 0; border-radius: 0; margin: 0; border-collapse: collapse;
}
.woocommerce table.shop_table th,
.woocommerce table.shop_table td {
  border: 0; border-bottom: 1px solid var(--hairline);
  padding: 12px 10px; vertical-align: middle;
}
.woocommerce table.shop_table th { color: var(--ink); font-weight: 650; }
.woocommerce table.shop_table td.product-name a { font-weight: 600; }
.woocommerce table.shop_table .amount { font-variant-numeric: tabular-nums; }

/* ---- pagination: quiet pills, the current one in chrome ----------------- */
.woocommerce nav.woocommerce-pagination { margin-top: var(--loose); }
.woocommerce nav.woocommerce-pagination ul { display: flex; justify-content: center; gap: 6px; border: 0; margin: 0; }
.woocommerce nav.woocommerce-pagination ul li { border: 0; overflow: visible; }
.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; height: 36px; padding: 0 10px;
  border: 1px solid var(--hairline); border-radius: var(--radius);
  color: var(--ink); background: transparent; line-height: 1;
}
.woocommerce nav.woocommerce-pagination ul li span.current {
  background: var(--chrome); border-color: var(--chrome); color: var(--reversed);
}
.woocommerce nav.woocommerce-pagination ul li a:hover {
  background: transparent; border-color: var(--accent); color: var(--accent);
}

/* preview chrome only */
.orca-meta {
  position: fixed; right: 12px; bottom: 12px; z-index: 9;
  background: rgba(20,20,20,.92); color: #fff; border-radius: 6px;
  padding: 10px 12px; font: 11px/1.55 ui-monospace, monospace; max-width: 280px;
}
.orca-meta b { color: #8FD6BC; } .orca-meta a { color: #8FD6BC; }
/* Ivywild pattern utilities for "orca-". Generated from the design tokens —
   edit the tokens in Orca and re-push rather than editing this block, which is
   replaced on every push. Hand-written CSS outside the markers is preserved. */

/* ---- Never scroll sideways. House rule, no exceptions unless the horizontal
   scroll IS the feature (a carousel, a wide table). Sideways scroll on a
   marketing page always reads as broken.

   `clip` rather than `hidden`: hidden makes the element a scroll container,
   which silently breaks `position: sticky` on headers.

   `min-width: 0` is the one that actually matters here. Flex children default
   to `min-width: auto`, so they refuse to shrink below their content — in a
   nowrap row of three cards, a long word pushes the row past 100% and the whole
   page scrolls. This is the most common cause of overflow in generated
   layouts, and it is invisible until some real copy happens to be long. */
html{overflow-x:clip}
body{overflow-x:clip;max-width:100%}
.e-con,.e-con-inner,.elementor-widget,.elementor-widget-container{min-width:0}
img,video,iframe,svg{max-width:100%;height:auto}
pre,code,table{max-width:100%;overflow-x:auto}

/* ---- the quote form ----------------------------------------------------
   Raw markup from core/forms/html.ts; quote.js in the connect plugin runs
   it. Inputs on the 4px radius and the hairline; tap targets are HEIGHT,
   which is what a thumb finds; a revealed block indents under the choice
   that asked for it, so the dependency reads on the page the way it reads
   in the document. */
/* THE ROOM ITS OWN HEIGHT. The band holds at least a viewport minus the
   header, so the card floats in a ground of its own instead of squeezing
   between neighbors -- dvh where the browser has it, vh where it does not. */
.orca-section.orca-qf-band{min-height:calc(100vh - var(--header-h,68px));
  min-height:calc(100dvh - var(--header-h,68px));
  display:flex;align-items:center}
.orca-qf-card{max-width:720px;margin:0 auto;width:100%}
.orca-qf{max-width:640px;margin:0 auto}
/* A closed box says so. The chosen ones stay live, so changing your mind is
   one untick, never a hunt for which box to free. */
.orca-qf-option input:disabled+span{opacity:.45}
.orca-qf-choices.qf-full .orca-qf-option>label{cursor:default}
.orca-qf-field{margin:16px 0}
.orca-qf-label{display:block;font-weight:600;margin-bottom:8px}
.orca-qf input[type=text],.orca-qf input[type=email],.orca-qf input[type=tel],
.orca-qf input[type=number],.orca-qf input[type=date],.orca-qf input[type=time],
.orca-qf input[type=url],.orca-qf select,.orca-qf textarea{
  width:100%;padding:10px 12px;font:inherit;color:inherit;
  border:1px solid var(--hairline);border-radius:var(--radius,4px);background:#fff}
.orca-qf-choices{display:flex;flex-direction:column;gap:2px}
.orca-qf-option>label,.orca-qf-toggle{
  display:flex;align-items:center;gap:10px;min-height:44px;cursor:pointer}
.orca-qf-option input,.orca-qf-toggle input{width:18px;height:18px;accent-color:#8B2E1F}
.orca-qf [data-qf-when]{margin:4px 0 8px 28px;padding-left:12px;border-left:2px solid var(--hairline)}
/* HIDDEN MEANS GONE. The script drives the steps and the nav with the
   hidden attribute, and the UA's [hidden] rule loses to ANY author display
   -- including the kit's own button styling -- which is how Back, Next and
   the submit were all on screen at once on step 1 of 8. */
[data-qf] [hidden]{display:none!important}

/* Helper prose under a field label -- quieter than the label, above the control. */
.orca-qf-desc{font-size:.85em;opacity:.75;margin:2px 0 8px;max-width:var(--measure,62ch)}
.orca-qf-step{border:0;padding:0;margin:0}
.orca-qf-step-title{font-family:'Oswald', system-ui, sans-serif;font-weight:600;font-size:1.25rem;padding:0;margin-bottom:8px}
.orca-qf-nav{display:flex;align-items:center;gap:16px;margin-top:32px}
.orca-qf-progress{margin-left:auto;font-size:13px;color:var(--ink-muted)}
.orca-qf-nav .orca-btn,.orca-qf-nav .orca-btn-out{font-family:'Oswald', system-ui, sans-serif}
.orca-qf-hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
.orca-qf-error{color:#7f1d1d;font-size:14px}
.orca-qf-done{font-weight:600}
.orca-qf .qf-invalid{border-color:#b91c1c!important}

/* THE MAP FILLS ITS HALF. An iframe has no intrinsic size: unstyled it
   renders 300x150 -- or 0 inside a flex column -- so the contact panel's map
   half reserved six hundred pixels and painted none of them. The column was
   there; the map inside it was a zero-height strip. */
.orca-map{display:flex}
.orca-map iframe,.orca-map img{width:100%;height:100%;min-height:320px;border:0;display:block;object-fit:cover}

/* ---- the footer's fittings ----------------------------------------------
   The footer logo is CAPPED AT THE HEADER LOGO'S HEIGHT -- the two marks are
   the same mark, and a footer logo four times the header's reads as a
   poster. 44px is the header's own cap: header-h-compact minus its 8px of
   air, the number the header comment has always named. */
.orca-foot-logo img{max-height:44px;width:auto}
/* Two columns past five items. break-inside keeps a link from snapping in
   half at the column boundary. */
.orca-foot-links-2 ul{columns:2;column-gap:40px}
.orca-foot-links-2 li{break-inside:avoid}
/* The social icons are Elementor's own social-icons widget -- the networks'
   real marks, inlined as SVG by its font-icon pipeline. The widget setting
   carries the quiet coloring; this only adds the hover, so the accent
   arrives the way it does for every other link down here. */
.orca-foot-social .elementor-social-icon{background:transparent}
.orca-foot-social .elementor-social-icon:hover svg,
.orca-foot-social .elementor-social-icon:hover i{color:#8B2E1F;fill:#8B2E1F}

/* THE NAV, THE EYEBROWS AND THE BUTTONS ARE ONE VOICE (Nick): the small
   insistent things a site says. The nav takes it at its own size and weight;
   only the family is shared. */
.orca-nav .elementor-item,.orca-nav-list .elementor-item,
body.iw-menu-panel .elementor-nav-menu--dropdown a{font-family:'Oswald', system-ui, sans-serif}
/* THE EYEBROW WEARS THE ACCENT, and it has to OUTRANK the kit to do it.
   Elementor's theme style writes .elementor-kit-N h6 at 0,1,1 -- one class,
   one element -- and a bare .p-eyebrow at 0,1,0 loses to it, so the
   subheads face kept taking the eyebrows however plainly the rule was
   stated ("EYEBROW GETS ACCENT" -- Nick, 1 Sep). Scoped under the section
   it is 0,2,0 and wins without an !important. */
/* The class rides the widget WRAPPER; the h6 sits inside it. Both forms, so
   the accent reaches the element whether the kit styles h6 directly or not. */
.orca-section .orca-eyebrow,
.orca-section .orca-eyebrow h6,
.orca-section .orca-eyebrow .elementor-heading-title{font-family:'Oswald', system-ui, sans-serif;font-size:.75rem;letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:#8B2E1F;margin-bottom:.25rem}
/* ON A DARK SURFACE THE EYEBROW IS WHITE (Nick, 2 Sep): the accent reads on
   the warm grounds and dies over a photograph's scrim or a dark block. The
   accent rule above is 0,3,0, so these carry a fourth class -- and sit
   AFTER it, because the first attempt sat before it at equal weight and
   lost the tie. */
.orca-section.orca-photographic .orca-eyebrow,
.orca-section.orca-photographic .orca-eyebrow h6,
.orca-section.orca-photographic .orca-eyebrow .elementor-heading-title,
.orca-section.orca-statement .orca-eyebrow,
.orca-section.orca-statement .orca-eyebrow h6,
.orca-section.orca-statement .orca-eyebrow .elementor-heading-title,
.orca-section.orca-accent-cta .orca-eyebrow,
.orca-section.orca-accent-cta .orca-eyebrow h6,
.orca-section.orca-accent-cta .orca-eyebrow .elementor-heading-title,
.orca-section .orca-eyebrow.orca-wt,
.orca-section .orca-eyebrow.orca-wt h6,
.orca-section .orca-eyebrow.orca-wt .elementor-heading-title,
.orca-duo-block.on-dark .orca-eyebrow,
.orca-duo-block.on-dark .orca-eyebrow h6,
.orca-duo-block.on-dark .orca-eyebrow .elementor-heading-title{color:#fff}
/* THE PRICE LIST SPEAKS SUBHEADS (Nick, 30 Aug): a dish name is an interior
   heading, not a paragraph - the name and its price take the Subheads face,
   the description stays in the body face.

   !IMPORTANT ON THE FAMILY, and this is the whole fix (31 Aug). Elementor's
   own price-list widget CSS names the PRICE at a specificity a bare class
   cannot reach, so the shared declaration set the size, the weight and the
   color - and the price kept the HEADING face while the title took the
   subhead. Measured on the built page: title "Source Sans 3" 19px 600, price
   "haboro-contrast-extended" 19px 600. Same size, same weight, two faces
   ("the prices are supposed to be same font as titles" - Nick). One
   declaration, one face, and nothing downstream can take the price back. */
.orca-price-list .elementor-price-list-title,
.orca-price-list .elementor-price-list-price{font-family:'Oswald', system-ui, sans-serif!important;
  font-weight:600!important}
/* The dish name sits ON its description (Nick, 2 Sep): Elementor gives the
   header its own bottom margin and the item gap already does that job, so
   every dish read as two spaced rows. widget-price-list.min.css loads AFTER
   the kit stylesheet, so equal specificity loses on source order -- the
   section class is the extra weight. */
.orca-section .orca-price-list .elementor-price-list-item .elementor-price-list-header{margin-bottom:0}
.orca-h1{font-family:'Oswald', system-ui, sans-serif;font-weight:700;
  font-size:clamp(2.25rem,5vw,4rem);line-height:1.05;letter-spacing:-.01em}
.orca-h2{font-family:'Oswald', system-ui, sans-serif;font-weight:700;
  font-size:clamp(1.75rem,3vw,2.75rem);line-height:1.15}
.orca-section .orca-h3,.orca-h3{font-family:'Oswald', system-ui, sans-serif;font-weight:600;font-size:1.5rem;line-height:1.2}
.orca-section .orca-h4,.orca-h4{font-family:'Oswald', system-ui, sans-serif;font-weight:600;font-size:1.125rem;line-height:1.3}
.orca-wt,.orca-wt *{color:#fff}
/* Elementor's kit heading color arrives as `.elementor-kit-N h1` - (0,1,1) -
   so the single-class rule above loses on headings, and every reversed band on
   the 25 August build shipped brand-maroon headlines over its photograph or
   its accent color. The doubled class is the container-padding trick again:
   (0,2,1) beats the kit wherever the file order lands, without !important. */
.orca-wt.orca-wt h1,.orca-wt.orca-wt h2,.orca-wt.orca-wt h3,
.orca-wt.orca-wt h4,.orca-wt.orca-wt h5,.orca-wt.orca-wt h6,
h1.orca-wt.orca-wt,h2.orca-wt.orca-wt,h3.orca-wt.orca-wt,
h4.orca-wt.orca-wt,h5.orca-wt.orca-wt,h6.orca-wt.orca-wt{color:#fff}

/* A measure. Body copy running the full width of a boxed container is the
   single most common reason a generated page looks unfinished. */
.orca-lead{font-family:'PT Sans', system-ui, sans-serif;font-size:1.125rem;line-height:1.6;
  max-width:62ch;color:#262220}
.orca-lead p:last-child,.orca-muted p:last-child{margin-bottom:0}
.orca-muted{font-family:'PT Sans', system-ui, sans-serif;opacity:.72;max-width:60ch}

.orca-card{height:100%;padding:28px;border-radius:14px;background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.05),0 10px 28px rgba(0,0,0,.06)}
.orca-card .elementor-icon-box-title{margin-block:.6rem .35rem}
.orca-chip{display:inline-block;padding:6px 14px;border-radius:999px;
  border:1px solid #4A3B2A;font-size:.8125rem;font-weight:600;color:#4A3B2A}
.orca-steps{font-family:'Oswald', system-ui, sans-serif;font-size:2.75rem;line-height:1;color:#8B2E1F;opacity:.35}
.orca-quote{max-width:70ch;margin-inline:auto;text-align:center}

/* THE RULEBOOK'S BUTTON, in the utility layer too. This pill was 999px at
   14/30 padding while the rulebook's shape table says 4px and 8px 32px --
   the check enforced the rule against the design CSS and this layer quietly
   disagreed with it on the built site. btn-slot rides along so the header
   CTA, which wears that class and no other, obeys the same three numbers.
   The hover is the STYLE SWAP, not a dimmer: solid hovers to its own
   outline, outline hovers to solid, the border never changes width. */
.orca-btn .elementor-button,.orca-btn-slot .elementor-button{
  font-family:'Oswald', system-ui, sans-serif;background:#8B2E1F;color:#ffffff;
  border:2px solid #8B2E1F;border-radius:var(--radius,4px);
  padding:8px 32px;font-weight:600;
  transition:background .2s ease,color .2s ease}
.orca-btn .elementor-button:hover,.orca-btn-slot .elementor-button:hover{
  background:transparent;color:#8B2E1F}
.orca-btn-ghost .elementor-button{font-family:'Oswald', system-ui, sans-serif;background:transparent;color:#4A3B2A;
  border:2px solid #4A3B2A;border-radius:var(--radius,4px);padding:8px 32px;font-weight:600;
  transition:background .2s ease,color .2s ease}
.orca-btn-ghost .elementor-button:hover{background:#4A3B2A;color:#ffffff}
/* THE WHITE BUTTON GOES WHERE THE WHITE TEXT GOES (Nick, 1 Sep). On a
   reversed band -- the photographic surfaces and the statement -- an accent
   outline reads as smudge over a photograph; the button borrows the text's
   own color, and hover fills white with the ink, the same style swap as
   everywhere else. */
.orca-photographic .orca-btn-ghost .elementor-button,
.orca-photo .orca-btn-ghost .elementor-button,
.orca-statement .orca-btn-ghost .elementor-button,
.orca-accent-cta .orca-btn-ghost .elementor-button,
/* The hero's own CTA rides in btn-slot, not btn-ghost -- the white rule
   missed it and an accent outline sat on the photograph. Scoped to the
   band's inner so the header CTA floating OVER the hero keeps its solid
   accent: the header is chrome, not band content. */
.orca-photographic .orca-inner .orca-btn-slot .elementor-button,
.orca-photo .orca-inner .orca-btn-slot .elementor-button{
  color:#fff;border-color:#fff;background:transparent}
.orca-photographic .orca-btn-ghost .elementor-button:hover,
.orca-photo .orca-btn-ghost .elementor-button:hover,
.orca-statement .orca-btn-ghost .elementor-button:hover,
.orca-accent-cta .orca-btn-ghost .elementor-button:hover,
.orca-photographic .orca-inner .orca-btn-slot .elementor-button:hover,
.orca-photo .orca-inner .orca-btn-slot .elementor-button:hover{
  background:#fff;color:var(--ink,#1A1A1A);border-color:#fff}

/* THE CLASSES THE BUILDER ACTUALLY EMITS. buttons() in templates/kit.ts puts
   `{p}-btn-slot` and `{p}-btn-secondary` on the widget wrappers, and
   `{p}-btn-slot` rides in the rulebook block's own .elementor-kit-834 list above -
   ONE definition of the button's shape. A second filled rule sat here with
   the old pill numbers (999px at 12/28) and, winning by file order, quietly
   shipped the pill on every built site while the rulebook block and the
   check both said 4px and 8px 32px - invisible for as long as Open Range's
   orc- prototype snippet was forcing its own pill over both (found 9 Sep,
   the day the snippet came out). What stays here is only the HOVER at
   doubled specificity, so the kit's own
   `.elementor-kit-N .elementor-button:hover` never outranks the swap
   (Nick, 30 Aug: solid hovers to its own outline, the border never
   changes, so the swap costs no layout shift). */
.orca-btn-slot.orca-btn-slot .elementor-button:hover{filter:none;
  background:transparent;color:#8B2E1F;border-color:#8B2E1F}

/* SECONDARY BUTTONS HAVE BACKGROUND #0000. House rule, Nick, 27 Aug — stated
   after a secondary shipped as a light pill on the accent band. The widget
   carries BOTH classes (btn-slot btn-secondary), so at equal specificity the
   filled rule above and this one were decided by file order — and file order
   is not a thing to bet a design on. The class is doubled to outrank the
   filled rule wherever the two rules end up. The outline wears the BRAND and
   hovers to solid brand; its text is computed by contrast, never assumed. */
.orca-btn-secondary.orca-btn-secondary .elementor-button{background:#0000;color:#4A3B2A;
  border:2px solid #4A3B2A;border-radius:var(--radius,4px);padding:8px 32px;font-weight:600;
  transition:background .2s ease,color .2s ease}
.orca-btn-secondary.orca-btn-secondary .elementor-button:hover{filter:none;
  background:#4A3B2A;color:#ffffff;border-color:#4A3B2A}
/* ON THE DARK POSTER the secondary outline borrows the text's white
   (Nick's improvement list, 10 Sep) - the brand outline on near-black is
   a whisper. Same swap: the outline hovers to solid white. */
.orca-duo-block.orca-on-dark .orca-btn-secondary.orca-btn-secondary .elementor-button{
  background:#0000;color:#fff;border-color:#fff}
.orca-duo-block.orca-on-dark .orca-btn-secondary.orca-btn-secondary .elementor-button:hover{
  filter:none;background:#fff;color:var(--dark,#1a1a1a);border-color:#fff}

/* THE JUMP STRIP'S CHIPS ARE BUTTON WIDGETS, so the kit's global button style
   lands on them and ten quiet jump links shipped as ten loud accent pills.
   Same join as `{p}-btn-slot` above: our class is on the wrapper, Elementor's
   is on the anchor, and the rule that styles the anchor has to say both.
   Doubled wrapper class for the same reason as `{p}-wt` — the kit's own
   `.elementor-kit-N .elementor-button` is (0,2,1) and file order is not a
   thing to bet a design on. QUIET by default; LOUD only on the section the
   reader is in, which the strip's scroll-spy marks with aria-current. */
.orca-jump.orca-jump .elementor-button{background:transparent;color:var(--ink-muted,#262220);
  border:0;box-shadow:none;border-radius:999px;padding:8px 14px;
  font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase}
.orca-jump.orca-jump .elementor-button:hover{background:var(--band-tint,rgba(0,0,0,.05));
  color:var(--ink,#262220);filter:none}
.orca-jump.orca-jump .elementor-button[aria-current]{background:var(--accent,#8B2E1F);color:#fff}

/* A BUTTON IS NEVER THE COLOR OF THE SURFACE IT SITS ON. On the accent band
   an accent button is invisible — the statement's "Order online" shipped as
   bare white text. Reversed treatment on loud surfaces, stated per surface so
   the rule cannot depend on which band a button happens to land in. THE SAME
   SWAP applies on the cta row (Nick, 30 Aug: "on hover just swap button
   style outline-hover > solid, solid-hover > outline"): the solid white pill
   hovers to a white outline, the white outline hovers to a solid white pill,
   borders unchanged. */
.orca-accent-cta .orca-btn-slot .elementor-button{background:#fff;color:#8B2E1F;border-color:#fff}
.orca-accent-cta .orca-btn-slot.orca-btn-slot .elementor-button:hover{filter:none;
  background:transparent;color:#fff;border-color:#fff}
.orca-accent-cta .orca-btn-secondary.orca-btn-secondary .elementor-button,
.orca-statement .orca-btn-secondary.orca-btn-secondary .elementor-button{background:#0000;
  color:#fff;border-color:#fff}
.orca-accent-cta .orca-btn-secondary.orca-btn-secondary .elementor-button:hover,
.orca-statement .orca-btn-secondary.orca-btn-secondary .elementor-button:hover{
  background:#fff;color:#8B2E1F;border-color:#fff}
.orca-photographic .orca-btn-secondary.orca-btn-secondary .elementor-button{color:#fff;
  border-color:#fff}
.orca-photographic .orca-btn-secondary.orca-btn-secondary .elementor-button:hover{
  background:#fff;color:#262220;border-color:#fff}

/* Hero over a photograph. NO TEXT SHADOW: the scrim is a gradient dark exactly
   where the words are, and a drop shadow under it is the flat-wash-plus-shadow
   pattern the playbook forbids - it is what makes a headline look printed on
   fog. If a headline is hard to read here, the scrim is wrong, not missing. */
.orca-lead.orca-wt{color:rgba(255,255,255,.92)}

/* Media placeholders. Deliberately obvious — a slot that reads as unfinished is
   safer than a silent gap someone ships by accident. */
.orca-mediaslot{background-color:#efece7;background-image:
  repeating-linear-gradient(45deg,rgba(0,0,0,.035) 0 12px,transparent 12px 24px);
  border:1px dashed rgba(0,0,0,.18)}
.orca-mediaslot-label h6,.orca-mediaslot-label{font-family:'PT Sans', system-ui, sans-serif;
  font-size:.75rem;letter-spacing:.08em;text-transform:uppercase;
  color:rgba(0,0,0,.45);margin:0}

/* Rhythm. Consecutive sections of the same kind were doubling their padding. */
.orca-mediaslot+.orca-mediaslot{margin-top:16px}
@media(max-width:767px){
  .orca-h1{font-size:2.1rem}
  .orca-card{padding:22px}
  .orca-mediaslot{min-height:180px}
}


/* revision #17: Product image consistency
Please standardize product image sizes/crops where possible so the product grid looks cleaner */
.orca-card img { aspect-ratio: 1 / 1; object-fit: cover; width: 100%; height: auto; display: block; }

/* revision #19: Custom Order section
The current Custom Order section has a very large image with a relatively small call-to-action. We */
.orca-section .orca-group { flex: 1 1 50%; } .orca-section .orca-group .orca-btn { padding: 1em 2em; font-size: 1.15em; transition: transform 0.2s ease, opacity 0.2s ease; } .orca-section .orca-group .orca-btn:hover { transform: translateY(-2px); } @media (prefers-reduced-motion: reduce) { .orca-section .orca-group .orca-btn { transition: none; } }
/* --- orca:utilities:end --- *//* End custom CSS */