/* ============================================================
   OSJ Sharp — layout: container, sections, chrome, grids
   Mobile-first. Breakpoints, per README "Responsive behavior":
     761px  — out of single-column; gutters 20px -> 40px
     1001px — sticky rails, split layouts, 3/4-up grids
     1121px — full nav bar and header search
   ============================================================ */

.osj-container {
  width: 100%;
  max-width: var(--container-xl);
  margin-inline: auto;
  padding-inline: var(--gutter-mobile);
}
.osj-container--narrow { max-width: var(--container-md); }

.osj-section { padding-block: 56px; }
.osj-section--tight { padding-block: 40px; }
.osj-section--flush-top { padding-block-start: 0; }
.osj-section--flush-bottom { padding-block-end: 0; }
.osj-section--alt { background: var(--surface-alt); }
.osj-section--ink { background: var(--ink-900); color: var(--text-on-dark-body); }

@media (min-width: 761px) {
  .osj-container { padding-inline: var(--section-inline); }
  .osj-section { padding-block: 72px; }
}
@media (min-width: 1001px) {
  .osj-section { padding-block: var(--section-block); }
  .osj-section--tight { padding-block: 80px; }
}

/* ============================================================
   Grids
   ============================================================ */
.osj-grid { display: grid; gap: var(--grid-gap); grid-template-columns: minmax(0, 1fr); }

@media (min-width: 761px) {
  .osj-grid--3, .osj-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1001px) {
  .osj-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .osj-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Two-column split — hero, banner strips, About, the SWU band. */
.osj-split { display: grid; gap: 36px; grid-template-columns: minmax(0, 1fr); align-items: center; }
@media (min-width: 1001px) {
  .osj-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-8); }
  .osj-split--hero { grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr); gap: 48px; }
  .osj-split--media-lead { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 56px; }
  .osj-split--copy-lead { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 64px; }
  /* Media-first in source order, copy-first on screen — keeps the reading
     order sane for screen readers while the ink banner alternates visually. */
  .osj-split--reverse > :first-child { order: 2; }
}

/* ============================================================
   Announcement marquee
   ============================================================ */
.osj-announce {
  position: relative;
  z-index: var(--z-announce);
  display: flex;
  align-items: center;
  height: var(--announce-h);
  overflow: hidden;
  background: var(--ink-900);
  color: var(--amber-400);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.osj-announce__track {
  display: flex;
  width: max-content;
  animation: osj-marquee 38s linear infinite;
  will-change: transform;
}
.osj-announce__group { display: flex; gap: 56px; padding-right: 56px; align-items: center; }
.osj-announce__group span { white-space: nowrap; }
.osj-announce__sep { color: #8C6B2E; }

@keyframes osj-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* A 38s scroll that cannot be paused is a WCAG 2.2.2 failure once it runs
   past five seconds. Hover and focus stop it; reduced-motion never starts it. */
.osj-announce:hover .osj-announce__track,
.osj-announce:focus-within .osj-announce__track { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .osj-announce__track { animation: none; }
  /* Without the scroll the duplicate track is dead weight and would overflow. */
  .osj-announce__group[aria-hidden="true"] { display: none; }
  .osj-announce { justify-content: center; }
  .osj-announce__group { flex-wrap: wrap; gap: var(--space-5); padding-right: 0; justify-content: center; }
}

/* ============================================================
   Header
   ============================================================ */
.osj-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--glass-panel);
  backdrop-filter: var(--blur-panel);
  -webkit-backdrop-filter: var(--blur-panel);
  border-bottom: 1px solid var(--border-on-dark-soft);
}
/* backdrop-filter is not universal; without it the translucent fill would let
   product photography scroll through the nav. Fall back to solid ink. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .osj-header { background: var(--ink-900); }
}

.osj-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  height: var(--header-h);
}

.osj-brand { display: flex; align-items: center; gap: 11px; flex-shrink: 0; }
.osj-brand:hover { text-decoration: none; }
.osj-brand__mark {
  display: inline-block;
  width: 26px;
  height: 30px;
  background: var(--gradient-mark);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}
.osj-brand__mark img { width: 100%; height: 100%; object-fit: contain; }
/* A real uploaded logo replaces the hexagon placeholder wholesale. */
.osj-brand__mark--logo { background: none; clip-path: none; width: auto; height: 40px; }
/*
 * The uploaded logo is black artwork and the header is near-black, so it read
 * as a smudge. brightness(0) flattens it to solid black whatever its source
 * colours, then invert(1) makes it solid white — which is what the lockup needs
 * against every dark band on the site.
 *
 * This is a stopgap for a monochrome mark. If a logo with real colour in it is
 * ever uploaded, drop this rule and supply a light variant instead, because the
 * filter would flatten that colour away.
 */
/*
 * Sizing must key off the height, not the width. The parent is width:auto, so
 * the base rule's width:100% is a cyclic reference: Blink resolves it from the
 * aspect ratio, WebKit falls back to the image's intrinsic width. With a 440px
 * logo on a 440px iPhone viewport that box ate the whole header and pushed the
 * wordmark and the cart off-screen, while object-fit kept the artwork looking
 * correctly small. Height is definite here, so resolve from it and let width
 * follow.
 */
.osj-brand__mark--logo img {
  filter: brightness(0) invert(1);
  width: auto;
  height: 100%;
  max-width: 45vw;
}
.osj-brand__name {
  font-family: var(--font-display);
  font-weight: var(--weight-black);
  font-size: 15px;
  letter-spacing: var(--tracking-snug);
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--sand-50);
}

/* Direct children throughout. The mega menu panel is rendered inside the Shop
   <li> so that it lands in the right place in the tab order, which puts its
   lists and links inside .osj-nav — a descendant selector here turns the
   panel's ten columns into one nowrap flex row that overflows the viewport. */
.osj-nav { display: none; }
.osj-nav > ul { display: flex; gap: 28px; align-items: center; list-style: none; white-space: nowrap; }
.osj-nav > ul > li > a { color: var(--sand-200); font-size: var(--text-sm); font-weight: var(--weight-medium); }
.osj-nav > ul > li > a:hover { color: var(--amber-400); text-decoration: none; }
.osj-nav > ul > .current-menu-item > a,
.osj-nav > ul > .current-menu-parent > a,
.osj-nav > ul > .current-menu-ancestor > a { color: var(--amber-400); }

/* ------------------------------------------------------------
   Shop mega menu
   ------------------------------------------------------------ */
/* A chevron, drawn rather than iconed, so it can rotate with the panel. */
.osj-nav__item--mega > a::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 6px;
  vertical-align: 2px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform var(--dur-fast) var(--ease-out);
}
.osj-nav__item--mega > a[aria-expanded="true"]::after {
  transform: rotate(-135deg) translate(-2px, -2px);
}

.osj-mega {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  /* Opaque, and therefore no backdrop-filter: blurring a backdrop nothing can
     see through is pure compositing cost. */
  background: var(--panel-solid);
  border-bottom: 1px solid var(--border-on-dark-soft);
  box-shadow: var(--shadow-on-dark);
  /* Closed state is visibility, not display: it keeps the links out of the tab
     order for free, and unlike display:none it can be transitioned. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-6px);
  transition:
    opacity var(--dur-fast) var(--ease-out),
    transform var(--dur-fast) var(--ease-out),
    visibility 0s linear var(--dur-fast);
}
.osj-mega[data-open="true"] {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

/* No-JS path. Scoped to .no-js — with JavaScript the open state is owned by
   hover intent, and a bare :hover rule would fire instantly on pass-through
   and undo it. The panel lives inside the <li>, so :hover on the item covers
   the pointer travelling from the nav item down into the panel. */
html.no-js .osj-nav__item--mega:hover .osj-mega,
html.no-js .osj-nav__item--mega:focus-within .osj-mega {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

/* padding-block, not the padding shorthand: this element is also .osj-container
   and the shorthand would zero the inline gutter it exists to provide, putting
   the first column hard against the viewport edge.
   .osj-nav > ul sets nowrap so the bar never wraps; the panel is a block of
   prose-length links and must not inherit it. */
.osj-mega__inner { padding-block: var(--space-6) var(--space-5); white-space: normal; }

.osj-mega__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-5) var(--space-6);
  list-style: none;
  margin: 0;
  padding: 0;
}

.osj-mega__type {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-weight: var(--weight-black);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--sand-50);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--border-on-dark-soft);
}
.osj-mega__type:hover { color: var(--amber-400); text-decoration: none; }

.osj-mega__count {
  font-family: var(--font-mono);
  font-weight: var(--weight-regular);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  color: var(--sand-500);
}

.osj-mega__games { list-style: none; margin: 0; padding: 0; }
.osj-mega__games a {
  display: block;
  padding: 5px 0;
  font-size: var(--text-sm);
  line-height: 1.35;
  color: var(--sand-300);
}
.osj-mega__games a:hover { color: var(--amber-400); text-decoration: none; }
.osj-mega__more { color: var(--sand-500) !important; font-size: var(--text-xs) !important; }

.osj-mega__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin: var(--space-5) 0 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-on-dark-soft);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--sand-500);
}
.osj-mega__foot a { color: var(--amber-400); }

/* There is no hover on a phone and the drawer already carries this structure,
   so the panel is never reachable there. Matches the Quick view decision:
   done in CSS, because device-dependent markup cannot be page-cached. */
@media (max-width: 1000px), (hover: none), (pointer: coarse) {
  .osj-mega { display: none; }
  .osj-nav__item--mega > a::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .osj-mega { transition: none; }
  .osj-nav__item--mega > a::after { transition: none; }
}

.osj-header__actions { display: flex; align-items: center; gap: 14px; margin-left: auto; min-width: 0; flex-shrink: 0; }
.osj-header__actions > * { flex-shrink: 0; }

.osj-iconbtn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--border-on-dark-firm);
  border-radius: var(--radius-sm);
  background: rgba(251, 247, 240, 0.07);
  color: var(--sand-200);
}
.osj-iconbtn:hover { background: rgba(251, 247, 240, 0.14); color: var(--sand-50); }

.osj-search { display: none; }
.osj-search__form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 8px 12px;
  border: 1px solid var(--border-on-dark);
  border-radius: var(--radius-sm);
  background: rgba(251, 247, 240, 0.07);
  flex: 0 1 190px;
  min-width: 0;
  /* Anchors the results panel. The field is only 190px wide, so the panel is
     deliberately wider than its own form. */
  position: relative;
}

/* ------------------------------------------------------------
   Live search results
   ------------------------------------------------------------ */
.osj-search__results {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 340px;
  max-width: min(340px, calc(100vw - 32px));
  max-height: min(70vh, 460px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-2) 0;
  background: var(--panel-solid);
  border: 1px solid var(--border-on-dark-soft);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-on-dark);
  /* Above the sticky header's own stacking context but below the cart drawer. */
  z-index: var(--z-drawer);
}
.osj-search__results[hidden] { display: none; }

.osj-search__group {
  margin: var(--space-2) 0 2px;
  padding: 0 var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--sand-500);
}

.osj-search__option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 8px var(--space-4);
  color: var(--sand-200);
  font-size: var(--text-sm);
  line-height: 1.3;
}
.osj-search__option:hover { text-decoration: none; }
/* One highlight state for pointer and keyboard both — see the mousemove
   handler in osj-live-search.js. Two would mean two rows looking chosen. */
.osj-search__option.is-active { background: rgba(251, 247, 240, 0.07); color: var(--sand-50); }

.osj-search__option img {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  object-fit: cover;
  border-radius: var(--radius-xs);
  background: var(--ink-800);
}
.osj-search__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.osj-search__name {
  /* Two lines, then ellipsis. These product names run to 80 characters and an
     untruncated one makes a single row taller than the rest of the list. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.osj-search__price { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--sand-500); }
.osj-search__term { flex: 1; min-width: 0; }
.osj-search__meta { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--sand-500); }

.osj-search__empty {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: var(--sand-400);
}

.osj-search__all {
  margin-top: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-on-dark-soft);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--amber-400);
}

/* In the drawer the field is full width and there is no room to the side, so
   the panel simply follows the field. */
.osj-mobile-nav__search form { position: relative; }
.osj-mobile-nav__search .osj-search__results {
  left: 0;
  right: 0;
  width: auto;
  max-width: none;
  max-height: 50vh;
}
.osj-search__form svg { color: var(--sand-400); flex-shrink: 0; }
.osj-search__form input {
  width: 100%;
  min-width: 0;
  border: none;
  background: none;
  color: var(--sand-50);
  font-size: 13px;
}
.osj-search__form input::placeholder { color: var(--sand-400); }
/*
 * Clicking into search changes nothing.
 *
 * The wrapper used to grow a glow ring on :focus-within, which sat outside its
 * own border and made the field read as two nested boxes.
 *
 * Keying it to :focus-visible instead does not help: a text input matches
 * :focus-visible however it was focused, mouse included, because the browser
 * assumes typing is coming. So the ring is simply gone.
 *
 * That is acceptable here specifically because this is a text field — the
 * caret is itself the focus indicator, and it appears for keyboard and pointer
 * alike. Do not copy this to a button or a checkbox, where there is no caret
 * and removing the ring would leave keyboard users lost.
 *
 * outline alone is not enough. base.css draws the focus ring as a box-shadow
 * (--focus-glow) with a transparent outline behind it, so clearing the outline
 * removes nothing visible and the amber glow stays. Removing the wrapper's ring
 * left the input's own untouched, which is why this read as fixed for two
 * sessions while still lighting up on every click.
 */
.osj-search__form input:focus,
.osj-search__form input:focus-visible {
  outline: none;
  box-shadow: none;
}

.osj-cart-btn {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 9px 14px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--brand);
  color: var(--ink-900);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  transition: background var(--dur-base) var(--ease-out);
}
.osj-cart-btn:hover { background: var(--brand-hover); color: var(--ink-900); text-decoration: none; }
.osj-cart-btn svg { flex-shrink: 0; }

@media (min-width: 1121px) {
  .osj-nav { display: block; margin-left: var(--space-1); flex-shrink: 0; }
  .osj-search { display: block; }
  .osj-menu-toggle { display: none; }
}

/* Slim checkout header — no nav, no marquee. */
.osj-header--slim { position: static; }
.osj-header--slim .osj-header__inner { justify-content: space-between; }
.osj-header__secure {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--sand-400);
}
.osj-header__secure svg { color: var(--amber-400); }

/* ============================================================
   Mobile navigation panel
   ============================================================ */
.osj-mobile-nav {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: grid;
  grid-template-columns: 1fr;
  visibility: hidden;
}
.osj-mobile-nav[data-open="true"] { visibility: visible; }
.osj-mobile-nav__scrim {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background: var(--scrim);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.osj-mobile-nav__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 320px;
  max-width: 86%;
  height: 100%;
  background: var(--ink-900);
  color: var(--sand-50);
  border-right: 1px solid var(--border-on-dark);
  transform: translateX(-100%);
  transition: transform var(--dur-slow) var(--ease-out);
}
.osj-mobile-nav[data-open="true"] .osj-mobile-nav__scrim { opacity: 1; }
.osj-mobile-nav[data-open="true"] .osj-mobile-nav__panel { transform: translateX(0); }

.osj-mobile-nav__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 18px 20px;
  border-bottom: 1px solid var(--border-on-dark-soft);
}
.osj-mobile-nav__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border: none;
  background: none;
  color: var(--sand-400);
}
.osj-mobile-nav__close:hover { color: var(--sand-50); }

/* Header search has no home in the bar below 1120px, so it lives here. */
.osj-mobile-nav__search { padding: 16px 20px; border-bottom: 1px solid var(--border-on-dark-soft); }
.osj-mobile-nav__search form {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  padding: 0 12px;
  border: 1px solid var(--border-on-dark-firm);
  border-radius: var(--radius-sm);
  background: rgba(251, 247, 240, 0.07);
}
.osj-mobile-nav__search svg { color: var(--sand-400); flex-shrink: 0; }
.osj-mobile-nav__search input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  color: var(--sand-50);
  font-family: var(--font-body);
  font-size: 15px;
}
/* Same field, same reasoning as the header one above — the caret is the focus
   indicator and a text input cannot tell a click from a Tab. Both the input's
   own glow and the wrapper's :focus-within ring go, or tapping search in the
   drawer lights up when clicking it in the header does not. */
.osj-mobile-nav__search input:focus,
.osj-mobile-nav__search input:focus-visible {
  outline: none;
  box-shadow: none;
}
/*
 * 16px, or iOS Safari zooms the viewport on focus and never zooms back out
 * (MOBILE-VARIANT-HANDOFF §1.5).
 *
 * base.css already carries that rule for input[type="search"], but at the same
 * specificity as the 15px above — and layout.css loads after base.css, so the
 * 15px was winning on source order alone and the protection did nothing. Same
 * tie-plus-source-order trap the wc-block overrides hit. Repeated here rather
 * than raised in base.css, because base.css should stay the floor and layout
 * is where the conflict is.
 *
 * 1120px, not base.css's 760px. This field only exists inside the drawer, and
 * the drawer is the navigation for everything below 1121px where .osj-nav is
 * hidden. An iPad in portrait is 768px CSS, which lands in the gap between the
 * two numbers: it would get the drawer, and a 15px field, and the zoom.
 */
@media (max-width: 1120px) {
  .osj-mobile-nav__search input { font-size: 16px; }
}

.osj-mobile-nav__links { flex: 1; overflow-y: auto; padding: 8px 0; }
.osj-mobile-nav__links ul { list-style: none; }
.osj-mobile-nav__links a {
  display: flex;
  align-items: center;
  min-height: 52px;
  padding: 0 20px;
  color: var(--sand-200);
  font-size: 16px;
}
.osj-mobile-nav__links a:hover { color: var(--amber-400); text-decoration: none; background: rgba(251, 247, 240, 0.04); }

/* The first primary item carries the display face — it is the "Shop all" row. */
.osj-mobile-nav__primary > li:first-child > a {
  color: var(--sand-50);
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: 16px;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}
.osj-mobile-nav__primary .current-menu-item > a,
.osj-mobile-nav__secondary .current-menu-item > a { color: var(--amber-400); }

/* Shop-by-type disclosures in the drawer. 52px rows throughout, per
   MOBILE-VARIANT-HANDOFF §1.1 — including the summary, which is the tap target
   that opens the group. */
.osj-mobile-nav__eyebrow {
  margin: 6px 0 2px;
  padding: 0 20px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--sand-500);
}
.osj-mobile-nav__group > summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 52px;
  padding: 0 20px;
  color: var(--sand-200);
  font-size: 16px;
  cursor: pointer;
  list-style: none;
}
.osj-mobile-nav__group > summary::-webkit-details-marker { display: none; }
/* Own chevron, so it can sit at the end of the row and rotate on open. */
.osj-mobile-nav__group > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  margin-left: auto;
  border-right: 1.5px solid var(--sand-500);
  border-bottom: 1.5px solid var(--sand-500);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dur-fast) var(--ease-out);
}
.osj-mobile-nav__group[open] > summary::after { transform: rotate(-135deg); }
.osj-mobile-nav__group[open] > summary { color: var(--sand-50); }
.osj-mobile-nav__count {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-wider);
  color: var(--sand-500);
}
/* Indented, and a touch smaller, so the two levels are distinguishable
   without a second colour. */
.osj-mobile-nav__group > ul > li > a {
  min-height: 48px;
  padding-left: 34px;
  font-size: 15px;
  color: var(--sand-400);
}
.osj-mobile-nav__group .osj-mobile-nav__all { color: var(--amber-400); }

@media (prefers-reduced-motion: reduce) {
  .osj-mobile-nav__group > summary::after { transition: none; }
}

.osj-mobile-nav__rule { height: 1px; margin: 10px 20px; background: var(--border-on-dark-soft); }
.osj-mobile-nav__secondary a { color: var(--sand-400); font-size: 15px; }

.osj-mobile-nav__foot {
  padding: 16px 20px 22px;
  border-top: 1px solid var(--border-on-dark-soft);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--amber-400);
}

/* ============================================================
   Cart drawer
   ============================================================ */
.osj-drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: flex;
  justify-content: flex-end;
  visibility: hidden;
}
.osj-drawer[data-open="true"] { visibility: visible; }
.osj-drawer__scrim {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background: var(--scrim);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.osj-drawer__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 400px;
  max-width: 100%;
  height: 100%;
  background: var(--surface-page);
  border-left: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-drawer);
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-out);
}
.osj-drawer[data-open="true"] .osj-drawer__scrim { opacity: 1; }
.osj-drawer[data-open="true"] .osj-drawer__panel { transform: translateX(0); }

.osj-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
}
.osj-drawer__title {
  font-family: var(--font-display);
  font-weight: var(--weight-black);
  font-size: 15px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-strong);
}
.osj-drawer__close { border: none; background: none; padding: 4px; display: flex; color: var(--text-body); }
.osj-drawer__close:hover { color: var(--text-strong); }

/*
 * The AJAX fragment container sits between the panel and the body/footer it
 * swaps out, so the panel's flex column stops at this wrapper. Left as a plain
 * block it grows to fit its contents, .osj-drawer__body never receives a height
 * to scroll within, and the footer — subtotal and Checkout — is pushed past the
 * bottom of the screen. Five cart lines was enough to do it.
 *
 * Passing the constraint through keeps the markup as the fragment expects it.
 */
.osj-drawer__panel > [data-osj-drawer-contents] {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.osj-drawer__body {
  flex: 1;
  /* Without min-height a flex item refuses to shrink below its content, which
     is the difference between this scrolling and simply overflowing. */
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.osj-drawer__empty { text-align: center; padding: var(--space-8) 0; color: var(--text-muted); }

.osj-drawer__line { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 14px; align-items: start; }
.osj-drawer__line img { width: 72px; height: 72px; object-fit: cover; border-radius: var(--radius-sm); background: var(--surface-sunken); }
.osj-drawer__line-title {
  margin-bottom: 4px;
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
  line-height: 1.35;
  color: var(--text-strong);
}
.osj-drawer__line-title a { color: inherit; }
.osj-drawer__line-meta { margin-bottom: var(--space-2); font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text-muted); }
.osj-drawer__line-price { font-family: var(--font-mono); font-weight: var(--weight-semibold); font-size: var(--text-sm); color: var(--text-strong); }
.osj-drawer__line-actions { display: flex; align-items: center; gap: 12px; margin-top: var(--space-2); }
.osj-drawer__remove { border: none; background: none; padding: 0; font-size: 13px; color: var(--text-muted); text-decoration: underline; }
.osj-drawer__remove:hover { color: var(--danger); }

.osj-drawer__foot {
  padding: var(--space-5) var(--space-5) 26px;
  /* The drawer runs to the bottom of the screen, so the Checkout button lands
     under the iPhone home indicator without this. Resolves to 0 elsewhere. */
  padding-bottom: calc(26px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border-subtle);
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* Never let the footer be the thing that scrolls away. */
  flex: 0 0 auto;
}
.osj-drawer__subtotal {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-strong);
}
.osj-drawer__subtotal strong { font-weight: var(--weight-semibold); }
.osj-drawer__lead {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.osj-drawer.is-busy .osj-drawer__body { opacity: 0.5; pointer-events: none; }

/* ============================================================
   Footer
   ============================================================ */
.osj-footer { background: var(--ink-900); color: var(--text-on-dark-body); }
.osj-footer__inner { padding-block-start: 56px; }
.osj-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 36px;
  padding-bottom: 48px;
}
.osj-footer__col-head {
  margin-bottom: var(--space-4);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber-400);
}
.osj-footer nav ul { list-style: none; display: flex; flex-direction: column; gap: 11px; }
.osj-footer a { color: var(--sand-200); font-size: var(--text-sm); }
.osj-footer a:hover { color: var(--amber-400); text-decoration: none; }
.osj-footer__blurb { margin-bottom: var(--space-5); font-size: var(--text-sm); line-height: 1.6; color: var(--sand-400); max-width: 34ch; }

.osj-social { display: flex; gap: 10px; }
.osj-social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border-on-dark-firm);
  border-radius: var(--radius-sm);
  color: var(--sand-200);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: var(--weight-semibold);
}
.osj-social a:hover { border-color: var(--amber-400); color: var(--amber-400); }

.osj-colophon {
  display: flex;
  justify-content: space-between;
  gap: var(--space-5);
  flex-wrap: wrap;
  padding: 22px 0 28px;
  border-top: 1px solid var(--border-on-dark-soft);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
.osj-colophon a { color: var(--text-muted); }

/* Slim checkout footer. */
.osj-footer--slim .osj-colophon { border-top: none; padding: 26px 0; }

@media (min-width: 761px) {
  .osj-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1001px) {
  .osj-footer__inner { padding-block-start: 72px; }
  .osj-footer__grid { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); gap: 48px; padding-bottom: 56px; }
}

/* ============================================================
   Newsletter panel
   ============================================================ */
.osj-newsletter {
  display: grid;
  gap: 36px;
  align-items: center;
  padding: 32px var(--space-5);
  margin-bottom: var(--space-9);
  background: var(--surface-inverse-2);
  border: 1px solid rgba(230, 182, 92, 0.2);
  border-radius: var(--radius-lg);
}
.osj-newsletter__title {
  margin-bottom: 10px;
  font-size: 1.9rem;
  font-weight: var(--weight-ultra);
  line-height: 1.05;
  letter-spacing: -0.024em;
  text-transform: uppercase;
  color: var(--sand-50);
}
.osj-newsletter p { font-size: 15px; line-height: 1.6; color: var(--sand-400); max-width: 46ch; }
.osj-newsletter__form { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; }
.osj-newsletter__form input[type="email"] {
  flex: 1 1 220px;
  min-width: 0;
  padding: 13px 14px;
  border: 1px solid var(--border-on-dark-firm);
  border-radius: var(--radius-sm);
  background: rgba(251, 247, 240, 0.06);
  color: var(--sand-50);
  font-family: var(--font-body);
  font-size: 14.5px;
}
.osj-newsletter__form input[type="email"]::placeholder { color: var(--sand-500); }

@media (min-width: 1001px) {
  .osj-newsletter {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 64px;
    padding: 40px 44px;
    margin-bottom: 64px;
  }
}

/* ============================================================
   Breadcrumb
   ============================================================ */
.osj-breadcrumb {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.osj-breadcrumb a { color: var(--text-muted); }
.osj-breadcrumb a:hover { color: var(--text-strong); }
.osj-breadcrumb__sep { color: #C4B79E; margin: 0 4px; }
[data-theme="dark"] .osj-breadcrumb,
[data-theme="dark"] .osj-breadcrumb a { color: var(--sand-400); }
[data-theme="dark"] .osj-breadcrumb__sep { color: #6E6350; }
[data-theme="dark"] .osj-breadcrumb a:hover { color: var(--amber-400); }

/* ============================================================
   Scroll-reveal initial states. Set in CSS, not JS, so there is no
   flash of final-position content before osj-motion.js runs.
   The .osj-motion-ready class is written to <html> by an inline
   snippet in header.php; without JS the rules never apply and
   everything renders in place.
   ============================================================ */
.osj-motion-ready [data-reveal] {
  opacity: 0;
  will-change: transform, opacity;
}
.osj-motion-ready [data-reveal="fade"] { transform: translateY(22px); }
.osj-motion-ready [data-reveal="scale"] { transform: scale(0.96); }
.osj-motion-ready [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-reveal) var(--ease-out) var(--reveal-delay, 0ms),
              transform var(--dur-reveal) var(--ease-out) var(--reveal-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  .osj-motion-ready [data-reveal] { opacity: 1; transform: none; }
}
