/*
Theme Name: Astra Child - Siljora
Template: astra
Description: Custom child theme for the Siljora jewellery store, built on Astra.
Version: 5.37.0
Author: Siljora
*/

/* ==========================================================================
   Siljora custom styles
   Add all custom CSS below. Nothing here touches Astra core files, so
   parent theme updates stay safe.
   ========================================================================== */

/* ==========================================================================
   DESIGN TOKENS
   Single source of truth. Component rules below should reference these
   rather than introducing new literal values.
   ========================================================================== */
:root {
  /* -- Colour -------------------------------------------------------------
     Warm ivory ground, espresso anchor, muted champagne accent.
     The ground is deliberately a warm paper tone rather than near-white:
     it is what makes a white product card read as *elevated* and lets
     silver and platinum settings separate from the surface behind them.
     Roughly 65% ivory / 25% espresso / 10% champagne across the page. */
  --c-bg: #f5f0e9;              /* page ground: warm ivory paper */
  --c-surface: #ffffff;         /* product cards — reads as elevation */
  --c-surface-muted: #ece4d9;   /* image wells, alternating bands */
  --c-text: #1f1a16;            /* espresso: headings, primary copy */
  --c-text-muted: #645a52;      /* secondary copy, metadata (5.9:1) */
  --c-text-inverse: #ffffff;

  /* Two golds, deliberately. The champagne is for metal-like detail —
     hairlines, borders, icons, anything on espresso. The deeper ink is the
     only one used for small text on light, where champagne is just 2.3:1. */
  --c-accent: #c0a062;          /* muted champagne: decorative metal */
  --c-accent-ink: #7f6231;      /* deep champagne: legible gold text */
  --c-accent-soft: #c2988c;     /* rose gold: retained hover accent */
  --c-blush: #f1ded9;           /* washes only, never large fills */

  /* Dark surfaces — the anchor that gives the page rhythm and makes the
     jewellery glint. Used for the closing bands, not scattered around. */
  --c-dark: #17120f;            /* espresso band */
  --c-dark-raised: #1f1a15;     /* subtle layer on top of the band */
  --c-on-dark: #f3ece2;         /* ivory text on espresso (15.9:1) */
  --c-on-dark-muted: #a89c8e;   /* secondary on espresso (6.9:1) */
  --c-border-dark: rgba(243, 236, 226, 0.14);

  --c-border: rgba(31, 26, 22, 0.14);
  --c-border-light: rgba(31, 26, 22, 0.08);
  /* Interactive outline: form fields and outlined buttons need an edge you
     can actually locate. The hairline above is deliberately faint for
     dividers, which is too quiet to read as a control. */
  --c-border-strong: rgba(31, 26, 22, 0.3);
  --c-scrim: rgba(20, 16, 14, 0.62);

  /* -- Typography -------------------------------------------------------- */
  /* One face across the whole site. Tenorite was the request, but it ships
     only with desktop Microsoft 365 and its licence does not cover serving it
     from a website — so Figtree carries the design: the nearest web-licensed
     match, humanist-geometric with the same large x-height and round dots.
     Tenorite stays first in the stack, so dropping licensed files into
     /fonts (see inc/typography.php) switches the site over automatically. */
  --font-display: 'Tenorite', 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body: 'Tenorite', 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --fs-display: clamp(2.75rem, 5.5vw, 4.25rem);
  --fs-h1: clamp(2.25rem, 4.4vw, 3.5rem);
  --fs-h2: clamp(1.75rem, 3.2vw, 2.5rem);
  --fs-h3: clamp(1.25rem, 2vw, 1.5rem);
  --fs-body-lg: 1.0625rem;
  --fs-body: 1rem;
  --fs-sm: 0.9375rem;
  --fs-xs: 0.8125rem;
  --fs-label: 0.6875rem;        /* letterspaced uppercase micro-labels */

  --lh-tight: 1.12;
  --lh-heading: 1.2;
  --lh-body: 1.65;
  --ls-label: 0.18em;
  --ls-caps: 0.1em;

  /* -- Spacing scale ----------------------------------------------------- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 5.5rem;
  --space-10: 7.5rem;

  /* 32-48px above and below each section, so two adjacent sections sit
     64-96px apart. It was 64-88px per side (up to 176px of empty space
     between sections), which read as dead air rather than breathing room. */
  --section-y: clamp(var(--space-6), 4vw, var(--space-7));
  --gutter: clamp(var(--space-5), 4vw, var(--space-7));

  /* -- Radius ------------------------------------------------------------ */
  --radius-sm: 4px;
  --radius-md: 10px;
  --radius-lg: 18px;
  --radius-pill: 999px;
  /* Buttons read as couture when they are near-square; the pill is kept
     only for small status/label chips (product badge, carousel dots). */
  --radius-btn: 2px;

  /* -- Elevation (warm-tinted, low alpha) -------------------------------- */
  --shadow-sm: 0 1px 2px rgba(33, 29, 26, 0.04), 0 2px 8px rgba(33, 29, 26, 0.04);
  --shadow-md: 0 8px 24px rgba(33, 29, 26, 0.07), 0 2px 6px rgba(33, 29, 26, 0.04);
  --shadow-lg: 0 24px 60px rgba(33, 29, 26, 0.12), 0 6px 16px rgba(33, 29, 26, 0.05);
  --shadow-xl: 0 40px 90px rgba(33, 29, 26, 0.16), 0 8px 20px rgba(33, 29, 26, 0.06);

  /* -- Motion ------------------------------------------------------------ */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: 160ms;
  --t-base: 280ms;
  --t-slow: 600ms;

  /* -- Layout ------------------------------------------------------------ */
  --container: 1180px;
  --control-h: 3rem;

  /* -- Legacy aliases ----------------------------------------------------
     Earlier component rules reference these names. Kept pointing at the
     tokens above so there is still one place to change a value. */
  --siljora-gold: var(--c-accent);
  --siljora-rose-gold: var(--c-accent-soft);
  --siljora-blush: var(--c-blush);
  --siljora-blush-deep: #e6c8c0;
  --siljora-black: var(--c-text);
  --siljora-cream: var(--c-bg);
  --siljora-ink: var(--c-text-muted);
  --siljora-font-display: var(--font-display);
  --siljora-font-body: var(--font-body);
}

body {
  background-color: var(--c-bg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--c-text-muted);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6,
.entry-content :where(h1, h2, h3, h4, h5, h6) {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-heading);
  color: var(--c-text);
  text-wrap: balance;
}

/* Astra and WooCommerce both fall back to the WordPress default blue for
   links. Route every link through the brand palette instead — this is what
   stops product/category links reading as stock WordPress. */
a {
  color: var(--c-text);
  text-decoration: none;
  transition: color var(--t-base) var(--ease-out);
}

a:hover,
a:focus {
  color: var(--c-accent-soft);
}

/* Visible, on-brand focus ring for keyboard users. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

::selection {
  background-color: var(--c-blush);
  color: var(--c-text);
}

/* ==========================================================================
   Header / navbar
   ========================================================================== */
/* Sticky, and condenses once the page scrolls: spacious on arrival, compact
   while browsing, so the cart stays reachable without the bar feeling heavy.
   js/custom.js toggles .siljora-scrolled. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 99;
  background-color: color-mix(in srgb, var(--c-bg) 88%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--c-border-light);
  transition: box-shadow var(--t-base) var(--ease-out),
    background-color var(--t-base) var(--ease-out);
}

/* Browsers without color-mix still get a solid, readable bar. */
@supports not (background-color: color-mix(in srgb, red 50%, transparent)) {
  .site-header {
    background-color: var(--c-bg);
  }
}

.site-header.siljora-scrolled {
  box-shadow: var(--shadow-sm);
}

/* Condense the bar itself. Astra sets the height on the inner row, so the
   padding transition has to live there. */
.site-header .ast-primary-header-bar {
  transition: padding var(--t-base) var(--ease-out);
  padding-top: var(--space-1);
  padding-bottom: var(--space-1);
}

.site-header.siljora-scrolled .ast-primary-header-bar {
  padding-top: 0;
  padding-bottom: 0;
}

.site-header .site-branding.ast-site-identity {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.site-header .custom-logo {
  max-height: 36px;
  width: auto;
  transition: max-height var(--t-base) var(--ease-out);
}

.site-header.siljora-scrolled .custom-logo {
  max-height: 30px;
}

.site-header .site-title a {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--c-text) !important;
}

/* ==========================================================================
   Brand monogram (footer)
   ========================================================================== */
.siljora-footer-mark {
  display: block;
  width: 30px;
  height: auto;
  margin: 0 auto 0.75rem;
  opacity: 0.9;
}

.site-header .main-header-menu .menu-link {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 400;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-text-muted);
  position: relative;
  transition: color var(--t-base) var(--ease-out);
}

.site-header .main-header-menu .menu-item:hover .menu-link,
.site-header .main-header-menu .current-menu-item .menu-link {
  color: var(--c-text);
}

.site-header .main-header-menu .menu-link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 0;
  height: 1px;
  background-color: var(--c-accent);
  transition: width var(--t-base) var(--ease-out);
}

.site-header .main-header-menu .menu-link:hover::after,
.site-header .main-header-menu .current-menu-item .menu-link::after {
  width: 100%;
}

/* Cart item: icon + label sit on one line (see siljora_cart_menu_icon()). */
.site-header .siljora-cart-item .menu-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.siljora-cart-icon {
  flex-shrink: 0;
  display: block;
}

/* The icon and its badge move as one on hover. */
.siljora-cart-icon-wrap {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  transition: transform var(--t-base) var(--ease-out);
}

.site-header .siljora-cart-item .menu-link:hover .siljora-cart-icon-wrap {
  transform: translateY(-2px);
}

/* Desktop shows the bag alone, like the account and search icons beside it.
   The word is hidden visually but kept for screen readers; the link is given
   a 44px box so an icon-only target is still easy to hit. */
@media (min-width: 922px) {
  /* The badge overhangs the bag to the right, so the link keeps a little
     extra room on that side; without it the badge sat about 5px from the
     Sign Up button. */
  .site-header .siljora-cart-item .menu-link {
    min-width: 44px;
    justify-content: center;
    margin-right: var(--space-2);
  }

  .site-header .siljora-cart-item .siljora-cart-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
}

/* ==========================================================================
   Hero section (Home page)
   Split layout: copy on the left, a tilt/shine product card on the right
   showcasing the real earring photo.
   ========================================================================== */
/* Deliberately no overflow clipping here: this section sits inside Astra's
   ~1200px container, so clipping would cut the arc's side cards at the
   container edge. Astra already sets overflow-x:hidden on <body>, which
   catches any spill at the page edge instead. */
.siljora-hero {
  position: relative;
  padding: var(--section-y) var(--gutter);
}

.siljora-hero-inner {
  position: relative;
  z-index: 1;
  max-width: 1180px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 3.5rem;
}

.siljora-hero-copy {
  flex: 1 1 460px;
  text-align: left;
}

/* Editorial micro-label: a hairline rule, then letterspaced caps. Reads as
   considered typography rather than decoration. */
.siljora-hero-eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-5);
}

.siljora-hero-eyebrow::before {
  content: '';
  width: var(--space-7);
  height: 1px;
  background-color: var(--c-accent);
  flex: none;
  opacity: 0.5;
}

.siljora-hero-title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-display);
  font-weight: 500;
  line-height: var(--lh-tight);
  letter-spacing: -0.01em;
  color: var(--c-text);
  margin: 0 0 var(--space-5);
  max-width: 13ch;
}

.siljora-hero-subtitle {
  font-size: var(--fs-body-lg);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--c-text-muted);
  max-width: 42ch;
  margin: 0 0 var(--space-7);
}

.siljora-hero-button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  background-color: var(--c-text);
  color: var(--c-text-inverse);
  border: 1px solid var(--c-text);
  border-radius: var(--radius-btn);
  padding: 1.15em 2.6em;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1;
  box-shadow: var(--shadow-md);
  transition: background-color var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out);
}

/* Arrow drawn in CSS so the markup stays clean; it slides on hover. */
.siljora-hero-button::after {
  content: '';
  width: 1.15rem;
  height: 1px;
  background-color: currentColor;
  transition: width var(--t-base) var(--ease-out);
}

.siljora-hero-button:hover::after {
  width: 1.9rem;
}

.siljora-hero-button:hover {
  background-color: var(--siljora-rose-gold);
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(201, 155, 142, 0.35);
}

/* -- Hero product carousel: the ".siljora-carousel" engine (see the
   Featured Products section below for the base rules), reshaped into an
   arc/coverflow track. Cards ride a shallow semi-circle: the next product
   waits half-visible at the right end, swings up to centre on its turn,
   then continues down to the left end as the following one takes over.
   Positions are class-driven (is-prev / is-active / is-next) so the JS
   only has to relabel slides — see js/featured-carousel.js. -- */
.siljora-carousel--hero {
  --siljora-arc-x: 265px;
  --siljora-arc-y: 62px;
  --siljora-arc-scale: 0.6;
  --siljora-arc-rotate: 8deg;
  --siljora-arc-duration: 900ms;
  --siljora-card-width: 360px;
  flex: 1 1 520px;
  /* Every slide is absolutely positioned, so this box has no in-flow
     content to derive a width from. Without an explicit width it collapses
     to 0 wherever flex-basis stops applying to the inline axis — i.e. when
     the hero stacks into a column on smaller screens. */
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
}

/* Side-on cards overhang this box by ~80px each way, so on the side-by-side
   layout the arc is pulled in from the container edge to give the incoming
   and outgoing cards room to sit fully visible. */
@media (min-width: 901px) {
  .siljora-carousel--hero {
    margin-left: 0;
    margin-right: 5.5rem;
  }
}

/* Still side-by-side but running out of room: tighten the arc so the outer
   cards stay on screen rather than pushing the page sideways. */
@media (min-width: 901px) and (max-width: 1200px) {
  .siljora-carousel--hero {
    --siljora-arc-x: 185px;
    --siljora-arc-y: 50px;
    --siljora-arc-scale: 0.5;
    --siljora-card-width: 260px;
    margin-right: 2rem;
  }

  .siljora-carousel--hero .siljora-carousel__media {
    max-width: 260px;
  }
}

.siljora-carousel--hero .siljora-carousel__viewport {
  min-height: 470px;
  background: none;
  box-shadow: none;
  border-radius: 0;
  /* Side cards fade out instead of being clipped, so nothing here may
     cut them off mid-card. */
  overflow: visible;
}

.siljora-carousel--hero .siljora-carousel__viewport:hover {
  transform: none;
  box-shadow: none;
}

.siljora-carousel--hero .siljora-carousel__track {
  min-height: 470px;
}

.siljora-carousel--hero .siljora-carousel__slide {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  /* Sized to the card, not the whole track. The arc transform is applied
     to this element, so a full-width slide would swing a 560px box 265px
     sideways and push the document's scroll area past the page edge. */
  width: var(--siljora-card-width);
  max-width: 100%;
  margin-inline: auto;
  transition: transform var(--siljora-arc-duration) var(--siljora-carousel-ease),
    opacity var(--siljora-arc-duration) ease;
}

/* Centre of the arc. */
.siljora-carousel--hero .siljora-carousel__slide.is-active {
  transform: translateX(0) translateY(0) scale(1) rotate(0deg);
  opacity: 1;
  pointer-events: auto;
  z-index: 3;
}

/* Right end of the arc — the product that is up next. */
.siljora-carousel--hero .siljora-carousel__slide.is-next,
.siljora-carousel--hero .siljora-carousel__slide.is-far-next {
  transform: translateX(var(--siljora-arc-x)) translateY(var(--siljora-arc-y))
    scale(var(--siljora-arc-scale)) rotate(var(--siljora-arc-rotate));
  pointer-events: none;
  z-index: 2;
}

/* Left end of the arc — the product that just had its turn. */
.siljora-carousel--hero .siljora-carousel__slide.is-prev,
.siljora-carousel--hero .siljora-carousel__slide.is-far-prev {
  transform: translateX(calc(-1 * var(--siljora-arc-x))) translateY(var(--siljora-arc-y))
    scale(var(--siljora-arc-scale)) rotate(calc(-1 * var(--siljora-arc-rotate)));
  pointer-events: none;
  z-index: 2;
}

/* Barely-there at the ends of the arc. The 900ms opacity transition on
   the slide means a card fades up as it swings toward the centre and
   fades back down as it leaves — the ghosting effect, not a hard cut. */
.siljora-carousel--hero .siljora-carousel__slide.is-prev,
.siljora-carousel--hero .siljora-carousel__slide.is-next {
  opacity: 0.12;
}

/* Queued further back: parked at the same end so they only fade, never
   fly across the arc. */
.siljora-carousel--hero .siljora-carousel__slide.is-far-prev,
.siljora-carousel--hero .siljora-carousel__slide.is-far-next {
  opacity: 0;
  z-index: 1;
}

.siljora-carousel--hero .siljora-carousel__media {
  position: relative;
  /* The card hugs its product image instead of filling the track, so the
     arc positions and the badge overhang stay inside the viewport. */
  height: auto;
  min-height: auto;
  width: 100%;
  max-width: 360px;
  /* No card: the photograph is the hero, with its name on a badge across the
     foot of it. The white mount and its shadow were there to hold cut-out
     images floating on transparency; these are product shots with their own
     backdrop, so the card only boxed them in. Depth comes from the drop-shadow
     the image itself carries. */
  background: transparent;
  border-radius: var(--radius-lg);
  padding: 0;
  box-shadow: none;
  /* Short enough that the card tracks the cursor instead of lagging behind it. */
  transition: transform 0.22s var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}

.siljora-carousel--hero .siljora-carousel__image-frame {
  display: block;
  width: 100%;
}

/* Product photographs are shot square (1024x1024), so the card is a square and
   the photograph fills it exactly — no mount, no bands down the sides. A photo
   that is not square is cropped to the frame rather than shrunk inside it,
   which is why the shop's own shots should stay square. */
.siljora-carousel--hero .siljora-carousel__image {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  max-height: none;
  object-fit: cover;
  border-radius: var(--radius-lg);
}

.siljora-carousel--hero .siljora-carousel__media:hover {
  box-shadow: none;
}

.siljora-carousel--hero .siljora-carousel__glow {
  width: 60%;
  height: 60%;
}

.siljora-carousel--hero .siljora-carousel__image {
  max-height: 300px;
}

.siljora-carousel--hero .siljora-carousel__badge {
  position: absolute;
  bottom: -14px;
  left: 50%;
  transform: translateX(-50%);
  background-color: var(--siljora-black);
  color: #fff;
  font-family: var(--siljora-font-body);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.65em 1.5em;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  box-shadow: var(--shadow-md);
}

@media (max-width: 900px) {
  /* Pictures first on a phone, then the copy and the button.
     `column-reverse` rather than reordering the markup: the desktop row wants
     copy-then-carousel, and the carousel holds nothing focusable and no
     heading — only decorative imagery with captions — so the visual swap
     cannot desync tab order or the heading outline. The button, which is the
     one focusable thing in the hero, stays inside the copy block. */
  .siljora-hero-inner {
    flex-direction: column-reverse;
    text-align: center;
    /* Stacked, the piece sits above the headline and its name badge hangs over
       the bottom edge of the photograph, so the gap has to clear the badge as
       well as the picture. */
    gap: 2rem;
  }

  .siljora-hero-copy {
    text-align: center;
    /* `flex: 1 1 460px` is a width basis in the desktop row, but once this
       column stacks the 460px becomes a HEIGHT floor — and the copy only
       needs about 340px, so it reserved 120px of empty space between the
       button and the carousel. Size to content instead. */
    flex: 0 0 auto;
  }

  /* The eyebrow is a flourish for the two-column hero. Wherever the hero
     stacks — phone and tablet alike — the carousel above already sets the
     scene, and the rule-plus-caps line competes with the title for width.
     Dropped rather than visually hidden: it is decorative framing, not
     information a screen reader would miss, and the <h1> below says the same
     thing. Its bottom margin goes with it, so the title sits at the stack
     gap with no dead space left behind. */
  .siljora-hero-eyebrow {
    display: none;
  }

  .siljora-hero-title,
  .siljora-hero-subtitle {
    margin-left: auto;
    margin-right: auto;
  }

  .siljora-carousel--hero {
    --siljora-arc-x: 165px;
    --siljora-arc-y: 46px;
    --siljora-arc-scale: 0.52;
    --siljora-card-width: 260px;
    /* Stacked layout: let the height follow the track instead of the
       row-direction flex-basis. */
    flex: 0 0 auto;
    max-width: 420px;
  }

  /* Only as tall as the card plus the arc's vertical offset; the old 400px
     left a band of empty ground above the picture. */
  .siljora-carousel--hero .siljora-carousel__viewport,
  .siljora-carousel--hero .siljora-carousel__track {
    min-height: 320px;
  }

  .siljora-carousel--hero .siljora-carousel__media {
    max-width: 260px;
  }
}

@media (max-width: 600px) {
  .siljora-hero {
    padding: 4.5rem 1.25rem;
  }

  /* The piece in the hero is the first thing anyone sees, so the card is given
     most of the screen's width. The arc that swings the two ghost cards out to
     the sides is pulled in to match: a wider card throws them further, and the
     slides are transformed rather than laid out, so an overhang would widen the
     document and give the whole page a sideways scroll. */
  .siljora-carousel--hero {
    max-width: none;
    /* Sized so the whole hero — piece, headline, line of copy and the button —
       lands on one phone screen. The arc comes in to match: a wider card throws
       the two ghost cards further out, and because they are transformed rather
       than laid out, any overhang widens the document and gives every page a
       sideways scroll. */
    --siljora-arc-x: min(18vw, 72px);
    --siljora-arc-y: 34px;
    --siljora-arc-scale: 0.38;
    --siljora-card-width: min(72vw, 270px);
  }

  .siljora-hero__copy,
  .siljora-hero-inner > *:not(.siljora-carousel) {
    padding-inline: var(--space-3);
  }

  /* The height follows the card rather than being stated: the card is square,
     so this is its width plus room for the name badge that hangs below it.
     A fixed height here is what stopped the section shrinking when the card
     did. */
  .siljora-carousel--hero .siljora-carousel__viewport,
  .siljora-carousel--hero .siljora-carousel__track {
    min-height: calc(min(72vw, 270px) + 2rem);
  }

  .siljora-carousel--hero .siljora-carousel__media {
    max-width: min(72vw, 270px);
    padding: 0;
  }

  /* The pictures take the card's full width, capped in height so a portrait
     shot cannot run away with the section.

     Cropping them to a single shape was tried and abandoned: the photographs
     are a mix of portrait and landscape, and a portrait crop cut both ends off
     the bracelet and left its middle empty. Nothing is cropped here — a
     landscape piece simply gets wider, which is most of the gain. */
  .siljora-carousel--hero .siljora-carousel__image-frame {
    display: block;
    width: 100%;
  }

  .siljora-carousel--hero .siljora-carousel__image {
    width: 100%;
    height: auto;
    max-height: none;
  }

  /* The section's own top and bottom bands: deeper again, so the hero reads as
     a full opening rather than a strip. The side padding goes, so the card can
     run out to the page's own gutter and read as a banner — the copy below it
     still sits on Astra's 20px container padding, which is gutter enough. */
  .siljora-hero {
    padding: 1.5rem 0 1.75rem;
  }

}

/* Scroll-reveal utility (paired with js/custom.js) */
.siljora-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
}

.siljora-reveal.siljora-in-view {
  opacity: 1;
  transform: translateY(0);
}

.siljora-reveal.siljora-delay-1.siljora-in-view { transition-delay: 0.12s; }
.siljora-reveal.siljora-delay-2.siljora-in-view { transition-delay: 0.24s; }
.siljora-reveal.siljora-delay-3.siljora-in-view { transition-delay: 0.36s; }

/* ==========================================================================
   WooCommerce
   Woo and Astra ship opinionated float/percentage layout with high
   specificity, so a few !important flags are needed to take the grid back.
   They are confined to layout resets on Woo's own classes.
   ========================================================================== */

/* -- Buttons (shared by archive, single, cart) -------------------------- */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce a.button.alt,
.woocommerce button.button.alt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  background-color: var(--c-text);
  color: var(--c-text-inverse);
  border: 1px solid var(--c-text);
  border-radius: var(--radius-btn);
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  line-height: 1;
  padding: 1.05em 2.1em;
  transition: background-color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out);
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover {
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-text);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.woocommerce a.button:active,
.woocommerce button.button:active {
  transform: translateY(0);
}

/* Quiet, outlined variant for the archive so the grid stays calm. */
.woocommerce ul.products li.product .button {
  background-color: transparent;
  color: var(--c-text);
  border-color: var(--c-border);
  padding: 0.9em 1.6em;
}

.woocommerce ul.products li.product .button:hover {
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-text);
}

/* -- Breadcrumb --------------------------------------------------------- */
.woocommerce .woocommerce-breadcrumb {
  font-size: var(--fs-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-text-muted);
  margin-bottom: var(--space-5);
}

.woocommerce .woocommerce-breadcrumb a {
  color: var(--c-text-muted);
}

.woocommerce .woocommerce-breadcrumb a:hover {
  color: var(--c-accent-ink);
}

/* -- Archive: results bar ---------------------------------------------- */
.woocommerce .woocommerce-result-count,
.woocommerce .woocommerce-ordering {
  margin-bottom: var(--space-6);
}

/* Count, search and sort in one row (see inc/shop-search.php). WooCommerce
   floats the count left and the sort control right; inside the row they
   become flex items instead, so the search field can sit between them and the
   whole bar can reflow on a phone. */
.siljora-shop-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-6);
}

.woocommerce .siljora-shop-toolbar .woocommerce-result-count,
.woocommerce .siljora-shop-toolbar .woocommerce-ordering {
  float: none;
  margin: 0;
}

/* The count takes the free space on the left, pushing search and sort right. */
.woocommerce .siljora-shop-toolbar .woocommerce-result-count {
  margin-right: auto;
}

.siljora-shop-search {
  position: relative;
  flex: 0 1 300px;
  margin: 0;
}

/* Same pill, border, type and hover as the sort control beside it, so the two
   read as a matched pair. Heavier selector: Astra styles input[type=search] at
   the weight of a single class and would otherwise win on source order. */
.siljora-shop-search input[type='search'].siljora-shop-search__field {
  width: 100%;
  height: 40px;
  margin: 0;
  padding: 0 44px 0 var(--space-4);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  color: var(--c-text);
  background-color: transparent;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-pill);
  box-shadow: none;
  transition: border-color var(--t-base) var(--ease-out);
  -webkit-appearance: none;
  appearance: none;
}

.siljora-shop-search input[type='search'].siljora-shop-search__field::placeholder {
  color: var(--c-text-muted);
  opacity: 1;
}

.siljora-shop-search input[type='search'].siljora-shop-search__field:hover {
  border-color: var(--c-accent);
}

.siljora-shop-search input[type='search'].siljora-shop-search__field:focus {
  border-color: var(--c-accent);
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}

/* The magnifier is the submit button, inside the pill's right end. A 40px
   square keeps it a comfortable target within the field's own height. */
.siljora-shop-search .siljora-shop-search__submit,
.siljora-shop-search .siljora-shop-search__submit:hover,
.siljora-shop-search .siljora-shop-search__submit:focus,
.siljora-shop-search .siljora-shop-search__submit:active {
  position: absolute;
  top: 0;
  right: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-pill);
  box-shadow: none;
  color: var(--c-text-muted);
  cursor: pointer;
  transition: color var(--t-base) var(--ease-out);
}

.siljora-shop-search .siljora-shop-search__submit:hover,
.siljora-shop-search .siljora-shop-search__submit:focus-visible {
  color: var(--c-text);
}

.siljora-shop-search .siljora-shop-search__submit:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: -4px;
}

/* A search with no matches: the field alone, centred above the message. */
.siljora-shop-toolbar--empty {
  justify-content: center;
}

.siljora-shop-toolbar--empty .siljora-shop-search {
  flex-basis: 420px;
}

/* On a phone the field gets its own full-width line on top, with the count
   and the sort control sharing the line beneath it. */
@media (max-width: 600px) {
  .siljora-shop-search {
    order: -1;
    flex: 1 1 100%;
  }

  .siljora-shop-search input[type='search'].siljora-shop-search__field {
    height: 44px;
  }

  .siljora-shop-search .siljora-shop-search__submit,
  .siljora-shop-search .siljora-shop-search__submit:hover,
  .siljora-shop-search .siljora-shop-search__submit:focus,
  .siljora-shop-search .siljora-shop-search__submit:active {
    width: 44px;
    height: 44px;
  }
}

.woocommerce .woocommerce-result-count {
  font-size: var(--fs-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.woocommerce .woocommerce-ordering select,
.woocommerce select.orderby {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  color: var(--c-text);
  background-color: transparent;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-5) var(--space-2) var(--space-4);
  transition: border-color var(--t-base) var(--ease-out);
}

.woocommerce .woocommerce-ordering select:hover {
  border-color: var(--c-accent);
}

/* -- Archive: product grid --------------------------------------------- */
.woocommerce ul.products,
.woocommerce-page ul.products {
  display: grid;
  /* Astra injects its own shop-columns value (4) via dynamic CSS that
     outranks this selector, which left a dead fourth column. Three gives
     the pieces room to breathe. */
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  gap: var(--space-8) var(--space-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The shop intro already carries the section's bottom padding; without this
   the header and the results bar sit ~164px apart. */
body.woocommerce-shop .siljora-section {
  padding-bottom: var(--space-6);
}

.woocommerce ul.products::before,
.woocommerce ul.products::after {
  content: none;
}

/* Undo Woo's float + percentage width so the grid governs placement. */
.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product {
  width: 100% !important;
  margin: 0 !important;
  float: none !important;
  clear: none !important;
  display: flex;
  flex-direction: column;
  text-align: left;
  /* Reveal-on-scroll initial state (js/custom.js adds .siljora-in-view;
     it also has a no-IntersectionObserver fallback that reveals all). */
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--t-slow) var(--ease-out),
    transform var(--t-slow) var(--ease-out);
}

.woocommerce ul.products li.product.siljora-in-view {
  opacity: 1;
  transform: translateY(0);
}

/* Gentle stagger across a row rather than every card at once. */
.woocommerce ul.products li.product:nth-child(3n + 2) { transition-delay: 80ms; }
.woocommerce ul.products li.product:nth-child(3n + 3) { transition-delay: 160ms; }

/* A fixed-ratio well: products photographed on different backgrounds and
   aspect ratios still line up on a common baseline. */
.woocommerce ul.products li.product a img,
.woocommerce ul.products li.product img {
  aspect-ratio: 1 / 1;
  object-fit: contain;
  width: 100%;
  height: auto;
  margin: 0 0 var(--space-5);
  padding: var(--space-6);
  background-color: var(--c-surface-muted);
  border-radius: var(--radius-md);
  transition: transform var(--t-slow) var(--ease-out),
    background-color var(--t-slow) var(--ease-out);
}

.woocommerce ul.products li.product:hover img {
  transform: scale(1.035);
  background-color: var(--c-blush);
}

.woocommerce ul.products li.product .woocommerce-loop-product__link {
  display: block;
}

.woocommerce ul.products li.product .woocommerce-loop-product__title,
.woocommerce ul.products li.product h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
  color: var(--c-text);
  padding: 0;
  margin: 0 0 var(--space-2);
}

.woocommerce ul.products li.product .ast-woo-product-category,
.woocommerce ul.products li.product .woocommerce-loop-product__category {
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-2);
}

.woocommerce ul.products li.product .price {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--c-text-muted);
  margin: 0 0 var(--space-5);
}

/* Push the button to the bottom so every card's CTA aligns. The button sits
   inside Astra's summary wrapper, not the card itself, so that wrapper has
   to be the flex column that grows — otherwise `margin-top: auto` does
   nothing and buttons sit at different heights across a row. */
.woocommerce ul.products li.product .astra-shop-summary-wrap {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}

.woocommerce ul.products li.product .button {
  margin-top: auto;
  align-self: flex-start;
}

.woocommerce ul.products li.product .star-rating {
  margin-bottom: var(--space-3);
}

/* -- Single product ----------------------------------------------------- */
.woocommerce div.product {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  column-gap: var(--space-9);
  align-items: start;
}

/* Anything that isn't gallery-or-summary should run the full width. */
.woocommerce div.product .woocommerce-notices-wrapper,
.woocommerce div.product .woocommerce-breadcrumb {
  grid-column: 1 / -1;
}

/* No sticky here. WooCommerce's own gallery CSS forces `position: relative`
   for the zoom overlay, which this rule cannot reliably outrank — and a `top`
   left behind on a relative element stops being a sticky offset and becomes a
   plain 64px shove downwards, which is exactly what it was doing. */
.woocommerce div.product .woocommerce-product-gallery {
  width: 100% !important;
  float: none !important;
  margin: 0;
  background-color: var(--c-surface-muted);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

/* Product photographs range from 0.56 to 1.33 in aspect, so without a fixed
   well a portrait shot made the column almost twice the height of the details
   beside it. A square well keeps the page compact — the details, price and Add
   to Cart all stay above the fold — and matches the cards used elsewhere. */
.woocommerce div.product .woocommerce-product-gallery__image img,
.woocommerce div.product .woocommerce-product-gallery img.wp-post-image {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border-radius: var(--radius-md);
}

/* Photographs carry their own background, so they fill the well; cut-outs on
   transparency stay contained so nothing is clipped. Classes come from
   inc/image-fit.php. */
.woocommerce div.product .woocommerce-product-gallery__image img.siljora-fit-photo {
  object-fit: cover;
}

.woocommerce div.product .woocommerce-product-gallery img {
  border-radius: var(--radius-md);
}

.woocommerce div.product div.summary,
.woocommerce div.product .summary.entry-summary {
  width: 100% !important;
  float: none !important;
  margin: 0;
}

.woocommerce div.product .product_title {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 500;
  line-height: var(--lh-heading);
  color: var(--c-text);
  margin: 0 0 var(--space-4);
  padding: 0;
}

.woocommerce div.product .posted_in,
.woocommerce div.product .product_meta {
  font-size: var(--fs-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.woocommerce div.product p.price,
.woocommerce div.product span.price {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 500;
  color: var(--c-text);
  margin: 0 0 var(--space-5);
}

.woocommerce div.product .woocommerce-product-details__short-description {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  color: var(--c-text-muted);
  max-width: 46ch;
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--c-border-light);
}

/* The add-to-cart row. WooCommerce ships the quantity box and the button as
   two unrelated controls — the field is sized in pixels, the button in ems off
   a small label size — so they came out 48px against 33px, each carrying its
   own stray bottom margin. Both are pinned to one height here and laid out as
   a single row. A variable product puts the same two controls inside
   .woocommerce-variation-add-to-cart, so that wrapper is the row instead. */
.woocommerce div.product form.cart {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}

/* A variable product's form also holds the swatches, which stack above. */
.woocommerce div.product form.variations_form {
  display: block;
}

.woocommerce div.product form.cart .woocommerce-variation-add-to-cart {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* The size-guide line belongs above the row, not beside it. */
.woocommerce div.product form.cart .woocommerce-variation-add-to-cart .siljora-size-guide {
  flex: 0 0 100%;
  margin: 0;
}

/* WooCommerce's own spacing, replaced by the row's gap. Astra writes these as
   `div.quantity` and `.button`, so the element and the second class are needed
   to outrank it rather than tie on specificity and lose on source order. */
.woocommerce div.product form.cart div.quantity,
.woocommerce div.product form.cart button.button.single_add_to_cart_button {
  margin: 0;
}

.woocommerce div.product form.cart .quantity input.qty {
  width: 4.5rem;
  height: var(--control-h);
  padding: 0 var(--space-2);
  text-align: center;
  font-family: var(--font-body);
  color: var(--c-text);
  background-color: transparent;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-btn);
}

/* The page's primary action: the same height as the field beside it, and wide
   enough to read as the thing to press. */
.woocommerce div.product form.cart button.button.single_add_to_cart_button {
  min-height: var(--control-h);
  padding: 0 var(--space-6);
}

/* On a phone the row is the full width, so the button takes what is left. */
@media (max-width: 600px) {
  .woocommerce div.product form.cart button.button.single_add_to_cart_button {
    flex: 1 1 auto;
  }
}

.woocommerce div.product .product_meta {
  padding-top: var(--space-5);
  border-top: 1px solid var(--c-border-light);
}

.woocommerce div.product .product_meta > span {
  display: block;
  margin-bottom: var(--space-2);
}

.woocommerce div.product .product_meta a {
  color: var(--c-accent-ink);
}

/* -- Single product: tabs ---------------------------------------------- */
.woocommerce div.product .woocommerce-tabs {
  grid-column: 1 / -1;
  margin-top: var(--space-7);
}

.woocommerce div.product .woocommerce-tabs ul.tabs {
  display: flex;
  gap: var(--space-6);
  margin: 0 0 var(--space-6);
  padding: 0 0 var(--space-3);
  border-bottom: 1px solid var(--c-border-light);
}

.woocommerce div.product .woocommerce-tabs ul.tabs::before {
  content: none;
}

/* Astra paints its own active-tab border in the WP admin blue via dynamic
   CSS that outranks a plain selector, so these two need !important. */
.woocommerce div.product .woocommerce-tabs ul.tabs li,
.woocommerce div.product .woocommerce-tabs ul.tabs li.active {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0;
  margin: 0;
  padding: 0;
}

/* Astra draws the active-tab marker as a 3px li::before in the WordPress
   admin blue (rgb(4,107,210)), and Woo adds its own grey rule on ul::before.
   Both are generated by selectors that outrank a plain `content: none`. */
.woocommerce div.product .woocommerce-tabs ul.tabs::before,
.woocommerce div.product .woocommerce-tabs ul.tabs::after,
.woocommerce div.product .woocommerce-tabs ul.tabs li::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li::after,
.woocommerce div.product .woocommerce-tabs ul.tabs li.active::before,
.woocommerce div.product .woocommerce-tabs ul.tabs li.active::after {
  content: none !important;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a {
  position: relative;
  display: block;
  padding: 0 0 var(--space-3);
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 0;
  height: 1px;
  background-color: var(--c-accent);
  transition: width var(--t-base) var(--ease-out);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li.active a,
.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover {
  color: var(--c-text);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li.active a::after {
  width: 100%;
}

.woocommerce div.product .woocommerce-tabs .panel {
  max-width: 62ch;
  color: var(--c-text-muted);
}

.woocommerce div.product .woocommerce-tabs .panel > h2:first-child {
  display: none;
}

/* -- Single product: related ------------------------------------------- */
.woocommerce div.product .related,
.woocommerce div.product .upsells {
  grid-column: 1 / -1;
  margin-top: var(--space-6);
  padding-top: var(--space-6);
  border-top: 1px solid var(--c-border-light);
}

/* The breadcrumb already names the category directly above the title, so
   Astra's category line is redundant repetition. */
.woocommerce div.product .summary .ast-woo-product-category {
  display: none;
}

.woocommerce div.product .related > h2,
.woocommerce div.product .upsells > h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
  font-style: italic;
  margin: 0 0 var(--space-7);
}

/* -- Cart / checkout ---------------------------------------------------- */
.woocommerce table.shop_table {
  border: 1px solid var(--c-border-light);
  border-radius: var(--radius-md);
  border-collapse: separate;
}

.woocommerce table.shop_table th {
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.woocommerce .cart_totals h2,
.woocommerce-cart h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 500;
}

.woocommerce .woocommerce-message,
.woocommerce .woocommerce-info,
.woocommerce .woocommerce-error {
  border-top-color: var(--c-accent);
  background-color: var(--c-surface-muted);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
}

.woocommerce .woocommerce-message::before,
.woocommerce .woocommerce-info::before {
  color: var(--c-accent-ink);
}

@media (max-width: 900px) {
  .woocommerce ul.products,
  .woocommerce-page ul.products {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: var(--space-7) var(--space-4);
  }

  .woocommerce div.product {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-7);
  }

  .woocommerce div.product .woocommerce-product-gallery {
    padding: var(--space-4);
  }
}

/* Phones: two pieces per row (the owner's choice), so the card is scaled down
   to fit a ~170px column — tighter photo padding, smaller type, and the
   button spanning the card so its label never wraps mid-word. */
@media (max-width: 600px) {
  .woocommerce ul.products,
  .woocommerce-page ul.products {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: var(--space-6) var(--space-3);
  }

  /* On a phone the square well is as wide as the screen, so it costs a whole
     screenful before the name and price are reached. A shallower well keeps the
     photograph generous and brings the details up. */
  .woocommerce div.product .woocommerce-product-gallery__image img,
  .woocommerce div.product .woocommerce-product-gallery img.wp-post-image {
    aspect-ratio: 5 / 4;
  }

  .woocommerce div.product .woocommerce-product-gallery {
    padding: var(--space-3);
  }

  .woocommerce ul.products li.product a img,
  .woocommerce ul.products li.product img {
    margin-bottom: var(--space-3);
    padding: var(--space-3);
  }

  .woocommerce ul.products li.product .woocommerce-loop-product__title,
  .woocommerce ul.products li.product h2 {
    font-size: 1rem;
    line-height: 1.3;
  }

  .woocommerce ul.products li.product .ast-woo-product-category,
  .woocommerce ul.products li.product .woocommerce-loop-product__category {
    font-size: 0.625rem;
    letter-spacing: 0.12em;
  }

  .woocommerce ul.products li.product .price {
    font-size: 0.95rem;
    margin-bottom: var(--space-3);
  }

  .woocommerce ul.products li.product .button {
    align-self: stretch;
    width: 100%;
    justify-content: center;
    padding-left: var(--space-2);
    padding-right: var(--space-2);
    font-size: 0.625rem;
    letter-spacing: 0.1em;
    text-align: center;
    white-space: nowrap;
  }

  /* Alternate the reveal delay per row of two, not three. */
  .woocommerce ul.products li.product:nth-child(3n + 2),
  .woocommerce ul.products li.product:nth-child(3n + 3) { transition-delay: 0ms; }
  .woocommerce ul.products li.product:nth-child(2n) { transition-delay: 80ms; }

  .woocommerce div.product form.cart {
    flex-wrap: wrap;
  }
}

/* ==========================================================================
   Section shell (shared by Featured Products, and future homepage sections)
   ========================================================================== */
.siljora-section {
  padding: var(--section-y) var(--gutter);
}

/* Astra puts a 64px margin above the content area. The shop page has no
   title or breadcrumb any more, so that margin is just dead space above
   the section heading. Astra's own rule is #primary-based, hence the
   extra classes here to win on specificity. */
body.woocommerce-shop .site-content #primary {
  margin-top: 0.5rem;
}

.siljora-section-inner {
  max-width: var(--container);
  margin: 0 auto;
}

.siljora-section-header {
  text-align: center;
  max-width: 46ch;
  margin: 0 auto var(--space-6);
}

/* Centred variant of the hero micro-label: hairline rules either side. */
.siljora-section-eyebrow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-4);
}

.siljora-section-eyebrow::before,
.siljora-section-eyebrow::after {
  content: '';
  width: var(--space-6);
  height: 1px;
  background-color: var(--c-accent);
  flex: none;
  opacity: 0.45;
}

/* Scoped through .siljora-section-header so it outranks the theme's
   ".entry-content h2" margin (0.7em, ~29px at this size). */
.siljora-section-header .siljora-section-title {
  font-size: var(--fs-h2);
  font-style: italic;
  font-weight: 500;
  line-height: var(--lh-heading);
  margin: 0 0 var(--space-4);
}

/* Also scoped, so the theme's ".entry-content p" bottom margin doesn't
   reintroduce a gap under the subtitle on pages that use the editor. */
.siljora-section-header .siljora-section-subtitle {
  font-size: var(--fs-body-lg);
  font-weight: 300;
  line-height: var(--lh-body);
  color: var(--c-text-muted);
  margin: 0;
}

/* ==========================================================================
   Featured Products — premium single-item carousel
   ========================================================================== */
.siljora-carousel {
  --siljora-carousel-duration: 900ms;
  --siljora-carousel-ease: cubic-bezier(0.16, 0.84, 0.44, 1);
  position: relative;
}

.siljora-carousel__viewport {
  position: relative;
  min-height: 460px;
  border-radius: var(--radius-lg);
  background: linear-gradient(160deg, var(--c-surface) 0%, var(--c-surface-muted) 100%);
  box-shadow: var(--shadow-md);
  overflow: hidden;
  touch-action: pan-y;
  transition: box-shadow var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
}

.siljora-carousel__viewport:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}

.siljora-carousel__track {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 460px;
}

.siljora-carousel__slide {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  align-items: center;
  gap: 2rem;
  padding: 3rem 4rem;
  opacity: 0;
  transform: translateX(40px) scale(0.94);
  transition: opacity var(--siljora-carousel-duration) var(--siljora-carousel-ease),
    transform var(--siljora-carousel-duration) var(--siljora-carousel-ease);
  pointer-events: none;
  z-index: 1;
}

.siljora-carousel__slide.is-active {
  opacity: 1;
  transform: translateX(0) scale(1);
  pointer-events: auto;
  z-index: 2;
}

/* -- Product media: transparent PNG floating in space, not boxed -- */
.siljora-carousel__media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-height: 320px;
  transform: perspective(900px) rotateX(0deg) rotateY(0deg) scale(1) translateY(0);
  transition: transform 0.22s var(--ease-out), box-shadow var(--t-base) var(--ease-out);
  will-change: transform;
}

.siljora-carousel__glow {
  position: absolute;
  width: 70%;
  height: 70%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(201, 155, 142, 0.28) 0%, rgba(201, 155, 142, 0) 72%);
  filter: blur(2px);
  opacity: 0.85;
  pointer-events: none;
  transition: transform var(--t-slow) var(--ease-out), opacity var(--t-slow) var(--ease-out);
}

.siljora-carousel__media:hover .siljora-carousel__glow {
  transform: scale(1.18);
  opacity: 1;
}

/* Frame carries the slow idle float; the <img> inside carries the
   cursor-driven tilt + hover zoom, so the two transforms never fight. */
.siljora-carousel__image-frame {
  position: relative;
  display: inline-flex;
  animation: siljora-carousel-float 6s ease-in-out infinite;
  animation-play-state: paused;
}

.siljora-carousel__slide.is-active .siljora-carousel__image-frame {
  animation-play-state: running;
}

/* The featured carousel's photograph sits inside a rounded card, so it is
   rounded to match — the hero's is rounded in its own block, where there is no
   card left behind it. */
.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__image,
.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__image-shine {
  border-radius: var(--radius-lg);
}

.siljora-carousel__image {
  position: relative;
  max-width: 100%;
  max-height: 340px;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 24px 32px rgba(36, 31, 28, 0.22));
  transition: filter var(--t-base) var(--ease-out);
}

.siljora-carousel__media:hover .siljora-carousel__image {
  filter: drop-shadow(0 34px 44px rgba(36, 31, 28, 0.32));
}

/* Sweeps via background-position rather than transform so the gleam stays
   inside its own box — the hero viewport no longer clips it. */
.siljora-carousel__image-shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 255, 255, 0.75) 50%, transparent 65%);
  background-size: 250% 100%;
  background-position: 180% 0;
  opacity: 0;
  pointer-events: none;
}

.siljora-carousel__media:hover .siljora-carousel__image-shine {
  animation: siljora-carousel-shine 1.1s ease forwards;
}

@keyframes siljora-carousel-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}

@keyframes siljora-carousel-shine {
  0% { background-position: 180% 0; opacity: 0; }
  15% { opacity: 0.9; }
  100% { background-position: -80% 0; opacity: 0; }
}

/* -- Product content, staggered entrance -- */
.siljora-carousel__content {
  text-align: left;
}

.siljora-carousel__stagger {
  display: block;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--t-slow) var(--ease-out), transform var(--t-slow) var(--ease-out);
  transition-delay: calc(var(--siljora-stagger, 0) * 90ms);
}

.siljora-carousel__slide.is-active .siljora-carousel__stagger {
  opacity: 1;
  transform: translateY(0);
}

.siljora-carousel__eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.78rem;
  color: var(--siljora-rose-gold);
  margin-bottom: 0.6rem;
}

.siljora-carousel__name {
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  font-style: italic;
  line-height: 1.2;
  margin: 0 0 0.85rem;
}

.siljora-carousel__desc {
  font-size: 1rem;
  font-weight: 300;
  color: var(--siljora-ink);
  max-width: 40ch;
  margin: 0 0 1.25rem;
}

.siljora-carousel__price {
  font-family: var(--siljora-font-display);
  font-size: 1.4rem;
  color: var(--siljora-black);
  margin-bottom: 1.75rem;
}

.siljora-carousel__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  background-color: var(--siljora-black);
  color: #fff;
  border-radius: 999px;
  padding: 0.85em 1.9em;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  font-weight: 500;
  width: fit-content;
  transition: background-color var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out), gap var(--t-base) var(--ease-out);
}

.siljora-carousel__cta:hover {
  background-color: var(--siljora-rose-gold);
  color: #fff;
  gap: 0.9rem;
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(201, 155, 142, 0.35);
}

.siljora-carousel__cta-arrow {
  transition: transform var(--t-base) var(--ease-out);
}

.siljora-carousel__cta:hover .siljora-carousel__cta-arrow {
  transform: translateX(3px);
}

/* -- Prev/next controls -- */
.siljora-carousel__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid rgba(36, 31, 28, 0.12);
  background-color: rgba(255, 255, 255, 0.8);
  color: var(--siljora-black);
  font-size: 1.4rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 3;
  transition: background-color var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}

.siljora-carousel__nav:hover {
  background-color: var(--siljora-black);
  color: #fff;
  transform: translateY(-50%) scale(1.06);
  box-shadow: 0 10px 24px rgba(36, 31, 28, 0.2);
}

.siljora-carousel__nav--prev { left: 1.5rem; }
.siljora-carousel__nav--next { right: 1.5rem; }

/* -- Footer: counter, progress, dots -- */
.siljora-carousel__footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  margin-top: 1.75rem;
}

.siljora-carousel__counter {
  font-family: var(--siljora-font-display);
  font-size: 0.95rem;
  color: var(--siljora-ink);
  letter-spacing: 0.05em;
  min-width: 3.5rem;
}

.siljora-carousel__progress {
  position: relative;
  width: 160px;
  height: 2px;
  background-color: rgba(74, 63, 59, 0.15);
  border-radius: 999px;
  overflow: hidden;
}

.siljora-carousel__progress-bar {
  position: absolute;
  inset: 0;
  width: 0%;
  background-color: var(--siljora-rose-gold);
  border-radius: 999px;
  transform-origin: left;
}

.siljora-carousel__progress-bar.is-running {
  animation: siljora-carousel-progress var(--siljora-autoplay-duration, 10000ms) linear forwards;
}

.siljora-carousel__progress-bar.is-paused {
  animation-play-state: paused;
}

@keyframes siljora-carousel-progress {
  from { width: 0%; }
  to { width: 100%; }
}

.siljora-carousel__dots {
  display: flex;
  align-items: center;
  /* Each dot is a 24px button around an 8px dot, so the visible spacing comes
     from the buttons themselves rather than a gap. */
  gap: 0;
}

/* The dot stays 8px, but the button around it is 24px so it can actually be
   tapped — WCAG asks for a 24px target, and a thumb is nowhere near 8px. The
   hit area is transparent, so the design is unchanged. */
.siljora-carousel__dot {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0;
}

.siljora-carousel__dot::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: rgba(74, 63, 59, 0.25);
  transition: background-color var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out);
}

.siljora-carousel__dot.is-active::before {
  background-color: var(--siljora-rose-gold);
  transform: scale(1.3);
}

.siljora-carousel__dot:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 50%;
}

@media (max-width: 900px) {
  .siljora-carousel__slide {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    /* A deeper bottom pad than top: the price and the call to action finish
       the card, and they need room under them rather than sitting on the
       edge. */
    padding: 2.5rem 2rem 3rem;
    text-align: center;
  }

  /* Once the slide stacks into one column it needs 549px, but nothing between
     601px and 900px raised the 460px floor — so the viewport, which clips at
     `overflow: hidden`, was cutting the call to action off the bottom of the
     card entirely. The slides are `position: absolute; inset: 0`, so the box
     cannot size to its content and the height has to be stated per band. */
  .siljora-carousel__viewport,
  .siljora-carousel__track {
    min-height: 620px;
  }

  .siljora-carousel__content {
    text-align: center;
  }

  .siljora-carousel__desc {
    margin-left: auto;
    margin-right: auto;
  }

  .siljora-carousel__cta {
    margin: 0 auto;
  }

  .siljora-carousel__media {
    min-height: 220px;
  }

  .siljora-carousel__image {
    max-height: 220px;
  }

  .siljora-carousel__nav {
    width: 38px;
    height: 38px;
    font-size: 1.2rem;
  }
}

@media (max-width: 600px) {
  .siljora-section {
    padding: 2rem 1.25rem;
  }

  /* The featured carousel has to arrive whole: on a phone the eyebrow,
     heading, photograph, name, price and the button should all be on screen
     at once, with no scroll to reach the thing you are meant to press.

     A 360x740 phone leaves about 680px under the sticky header, and the
     section was costing 920. Every part below is trimmed against that budget
     and the total lands near 650. The slides are absolutely positioned, so
     the viewport's stated height IS the budget — it cannot shrink to fit its
     contents, which is why the height and the contents are changed together.

     Scoped away from the hero carousel, which is a different shape and has
     its own sizes above. */
  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__viewport {
    border-radius: 20px;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__slide {
    padding: 1.5rem 1.25rem 1.75rem;
    gap: 1rem;
  }

  /* The photograph is the biggest single cost and the easiest to give back:
     it stays the hero of the card at 170px, rather than the 220 it had. */
  /* On one column the photograph has the whole card to itself, so it is sized
     by the card's width rather than held to a height. The section grows past a
     single screen on a short phone, which is the right trade: the piece is what
     the shopper is here for, and 160px of it was a thumbnail. */
  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__media {
    min-height: 0;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__image-frame {
    display: block;
    width: 100%;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__image {
    width: 100%;
    max-height: 320px;
    object-fit: contain;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__name {
    margin-bottom: 0.5rem;
  }

  /* Two lines introduce the piece; the product page carries the rest. Without
     the clamp a three-line description pushes the button off the screen,
     which is the whole problem being solved here. */
  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__desc {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-bottom: 0.75rem;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__price {
    margin-bottom: 0.9rem;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__footer {
    margin-top: 0.9rem;
  }

  /* Section headings on a phone: the same hierarchy, less air between the
     three lines. This applies to every section, which all gain from it. */
  .siljora-section-header {
    margin-bottom: var(--space-5);
  }

  .siljora-section-eyebrow {
    margin-bottom: var(--space-3);
  }

  .siljora-section-header .siljora-section-title {
    margin-bottom: var(--space-3);
  }

  .siljora-carousel__nav--prev { left: 0.75rem; }
  .siljora-carousel__nav--next { right: 0.75rem; }
}

/* Short phones (an iPhone SE is 667 tall, which leaves about 610 under the
   header) get a smaller photograph and a one-line description, so the same
   section still arrives whole rather than cutting the button off. Taller
   phones keep the generous version above. */
@media (max-width: 600px) and (max-height: 700px) {
  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__slide {
    padding: 1rem 1.25rem 1.25rem;
    gap: 0.75rem;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__image {
    max-height: 200px;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__desc {
    -webkit-line-clamp: 1;
    line-clamp: 1;
    margin-bottom: 0.5rem;
  }

  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__price {
    margin-bottom: 0.7rem;
  }

  /* The hero card is generous above, but on a short screen it would push the
     headline and the button out of the first view, so it comes back in. */
  .siljora-carousel--hero {
    --siljora-card-width: min(60vw, 215px);
  }

  .siljora-carousel--hero .siljora-carousel__viewport,
  .siljora-carousel--hero .siljora-carousel__track {
    min-height: calc(min(60vw, 215px) + 2rem);
  }

  .siljora-carousel--hero .siljora-carousel__media {
    max-width: min(60vw, 215px);
  }

  /* The copy comes in as well as the card: on a 667px screen the piece alone is
     not what overflows, the three lines of headline under it are. */
  .siljora-hero {
    padding: 1.25rem 0 1.5rem;
  }

  .siljora-hero-inner {
    gap: 1.5rem;
  }

  .siljora-hero-title {
    font-size: 2.1rem;
    line-height: 1.1;
  }

  .siljora-hero-copy p {
    margin-bottom: 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .siljora-carousel__slide {
    transition: opacity var(--t-base) var(--ease-out);
    transform: none !important;
  }

  .siljora-carousel__image-frame {
    animation: none !important;
  }

  .siljora-carousel__media {
    transition: none !important;
    transform: none !important;
  }

  /* The arc collapses to a plain crossfade: without transforms the side
     cards would stack on top of the centre one. */
  .siljora-carousel--hero .siljora-carousel__slide {
    transition: opacity var(--t-base) var(--ease-out);
    opacity: 0;
  }

  .siljora-carousel--hero .siljora-carousel__slide.is-active {
    opacity: 1;
  }

  .siljora-carousel__image-shine {
    display: none !important;
  }

  .siljora-carousel__viewport:hover {
    transform: none;
  }

  .siljora-carousel__media:hover .siljora-carousel__glow {
    transform: none;
  }

  .siljora-carousel__progress-bar.is-running {
    animation-duration: 10ms !important;
  }
}

/* ==========================================================================
   Footer columns (rendered by siljora_render_footer_columns() on the
   astra_footer_content_top hook, so it sits above Astra's copyright bar)
   ========================================================================== */
.siljora-footer {
  background-color: var(--siljora-cream);
  border-top: 1px solid var(--c-border-light);
  padding: var(--space-7) var(--gutter) var(--space-6);
}

.siljora-footer__inner {
  max-width: 1180px;
  margin: 0 auto;
}

.siljora-footer__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 3.5rem;
  text-decoration: none;
}

.siljora-footer__logo {
  width: 44px;
  height: auto;
}

.siljora-footer__brand-name {
  font-family: var(--siljora-font-display);
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--siljora-black);
}

.siljora-footer__columns {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 2.5rem;
  align-items: start;
}

.siljora-footer__heading {
  font-family: var(--siljora-font-body);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--siljora-black);
  margin: 0 0 1.5rem;
}

.siljora-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.siljora-footer__list li + li {
  margin-top: 0.85rem;
}

.siljora-footer__list a,
.siljora-footer__line a {
  color: var(--siljora-ink);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 300;
  transition: color var(--t-base) var(--ease-out);
}

.siljora-footer__list a:hover,
.siljora-footer__line a:hover {
  color: var(--siljora-rose-gold);
}

.siljora-footer__line {
  font-size: 0.95rem;
  font-weight: 300;
  color: var(--siljora-ink);
  margin: 0 0 0.85rem;
}

.siljora-footer__line strong {
  font-weight: 500;
  color: var(--siljora-black);
}

.siljora-footer__line--email {
  margin-top: 1.5rem;
}

/* No resting underline: the email sits alone on its own line, not inside a
   sentence, so it does not need one to read as a link, and it would clash
   with the sliding underline every other footer link now shares. */
.siljora-footer__line--email a {
  text-decoration: none;
}

@media (max-width: 900px) {
  .siljora-footer__columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2.5rem 2rem;
  }
}

@media (max-width: 600px) {
  .siljora-footer {
    padding: 3rem 1.25rem 2rem;
  }

  /* Two columns rather than one long stack: the four groups pair up as
     "We are Siljorah" beside "Support", then "Blogs" beside "Can we help
     you?", which halves how far the footer runs down a phone. */
  .siljora-footer__columns {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2.25rem 1.25rem;
  }

  .siljora-footer__brand {
    margin-bottom: 2.5rem;
  }
}

/* WooCommerce leaves this header element in place even when its title and
   description are removed (see siljora_clean_shop_header()); collapse the
   empty shell so it doesn't leave a gap above the products. */
.woocommerce-products-header:empty {
  display: none;
}

/* ==========================================================================
   Trust badges strip ([siljora_trust_badges])
   ========================================================================== */
.siljora-badges {
  background-color: var(--siljora-cream);
  border-top: 1px solid var(--c-border-light);
  padding: var(--section-y) var(--gutter);
}

.siljora-badges__inner {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.siljora-badges__item {
  text-align: center;
  padding: 0 2rem;
}

/* Hairline separators between columns, matching the reference. */
.siljora-badges__item + .siljora-badges__item {
  border-left: 1px solid rgba(176, 141, 87, 0.2);
}

.siljora-badges__icon {
  display: block;
  width: 52px;
  height: 52px;
  margin: 0 auto 1.5rem;
  color: var(--siljora-black);
}

.siljora-badges__icon svg {
  width: 100%;
  height: 100%;
}

.siljora-badges__title {
  font-family: var(--siljora-font-body);
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--siljora-black);
  margin: 0 0 0.6rem;
}

.siljora-badges__text {
  font-size: 0.95rem;
  font-weight: 300;
  color: var(--siljora-ink);
  margin: 0;
}

@media (max-width: 900px) {
  .siljora-badges__item {
    padding: 0 1rem;
  }

  .siljora-badges__title {
    font-size: 0.95rem;
  }
}

@media (max-width: 600px) {
  .siljora-badges {
    padding: 2.5rem 1.25rem;
  }

  .siljora-badges__inner {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  /* Stacked: the separator has to run horizontally instead. */
  .siljora-badges__item + .siljora-badges__item {
    border-left: 0;
    border-top: 1px solid rgba(176, 141, 87, 0.2);
    padding-top: 2.5rem;
  }
}

/* ==========================================================================
   Our Collections — category cards ([siljora_collections])
   ========================================================================== */
.siljora-collections {
  display: grid;
  /* auto-fit rather than a fixed count: the section is driven by whichever
     categories are passed to [siljora_collections], so the row reflows as
     categories are added instead of leaving an orphan card on its own. */
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: var(--space-5);
}

.siljora-collections__card {
  position: relative;
  display: block;
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  aspect-ratio: 3 / 4;
  background-color: var(--c-surface-muted);
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}

.siljora-collections__card:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}

.siljora-collections__media {
  position: absolute;
  inset: 0;
  display: block;
}

.siljora-collections__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--t-slow) var(--ease-out);
}

.siljora-collections__card:hover .siljora-collections__image {
  transform: scale(1.06);
}

.siljora-collections__placeholder {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(160deg, var(--siljora-blush) 0%, var(--siljora-cream) 60%, var(--siljora-blush-deep) 100%);
}

/* Scrim so the caption stays readable over any photo. */
.siljora-collections__card::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Deepened and carried further up the card: these photographs are bright
     cream satin, so the previous scrim left the caption around 4:1 against
     the lightest frames. Weighted to the lower third so the jewellery in
     the middle of the frame stays untouched. */
  background: linear-gradient(to top,
    rgba(14, 11, 9, 0.82) 0%,
    rgba(16, 13, 10, 0.55) 22%,
    rgba(20, 16, 14, 0.18) 42%,
    rgba(20, 16, 14, 0) 62%);
  pointer-events: none;
}

.siljora-collections__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1.75rem;
  z-index: 1;
  text-align: center;
  padding: 0 1rem;
}

.siljora-collections__count {
  display: block;
  font-size: 0.85rem;
  font-weight: 300;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.94);
  margin-bottom: var(--space-2);
}

.siljora-collections__name {
  display: block;
  font-family: var(--siljora-font-body);
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}

@media (max-width: 1100px) {
  /* Two up: four narrow cards at this width make the 3:4 frames too tall. */
  .siljora-collections {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* At half-width a 3:4 frame is ~620px tall, which makes the section
     enormous. Square is the right proportion for a two-up row. */
  .siljora-collections__card {
    aspect-ratio: 1 / 1;
  }
}

@media (max-width: 900px) {
  .siljora-collections {
    gap: var(--space-4);
  }

  .siljora-collections__name {
    font-size: 1.05rem;
  }
}

@media (max-width: 600px) {
  .siljora-collections {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  .siljora-collections__card {
    aspect-ratio: 4 / 3;
  }
}

/* ==========================================================================
   Accessibility
   ========================================================================== */

/* Touch targets. The label-sized type on buttons computes to ~30px tall,
   which is under the 44px comfortable-touch minimum, so enforce a floor on
   coarse pointers rather than inflating the desktop design. */
@media (max-width: 900px) {
  .siljora-hero-button,
  .siljora-carousel__cta,
  .woocommerce a.button,
  .woocommerce button.button,
  .woocommerce input.button,
  .woocommerce #respond input#submit,
  .woocommerce ul.products li.product .button,
  .woocommerce div.product form.cart .quantity input.qty,
  .woocommerce .woocommerce-ordering select,
  .woocommerce-product-gallery__trigger,
  .ast-on-card-button,
  .siljora-contact-submit {
    min-height: 44px;
  }

  /* Astra's on-card variant doesn't carry .button, so it needs naming. */
  .ast-on-card-button {
    display: inline-flex;
    align-items: center;
  }

  /* Tab links are the only way to reach the reviews panel on touch. */
  .woocommerce div.product .woocommerce-tabs ul.tabs li a {
    padding-top: var(--space-3);
    padding-bottom: var(--space-4);
  }

  .menu-toggle,
  .ast-mobile-menu-trigger-minimal {
    min-width: 44px;
    min-height: 44px;
  }

  /* Product titles in the grid are the primary tap target for the card. */
  .woocommerce ul.products li.product .woocommerce-loop-product__title {
    padding-block: var(--space-1);
  }
}

/* Global reduced-motion safety net. Component-level blocks above already
   disable the carousel arc, tilt and shine; this catches anything else
   (nav condense, hovers, reveals) so the site stays usable and still. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   The espresso close
   The page previously ran ivory from masthead to copyright, so it had no
   value contrast and no rhythm. The reassurance strip, footer and copyright
   bar now form one continuous dark band: it anchors the page, gives the
   gold monogram something to read as metal against, and frames the ivory
   product sections above it. Deliberately the only large dark area.
   ========================================================================== */
.siljora-badges,
.siljora-footer,
.site-below-footer-wrap {
  background-color: var(--c-dark);
  color: var(--c-on-dark-muted);
}

/* A single champagne hairline where the ivory meets the espresso. */
.siljora-badges {
  border-top: 1px solid var(--c-accent);
  box-shadow: inset 0 1px 0 rgba(192, 160, 98, 0.25);
}

.siljora-footer {
  border-top: 1px solid var(--c-border-dark);
}

/* -- Reassurance strip on dark ----------------------------------------- */
.siljora-badges__icon {
  color: var(--c-accent);
}

.siljora-badges__title {
  color: var(--c-on-dark);
}

.siljora-badges__text {
  color: var(--c-on-dark-muted);
}

.siljora-badges__item + .siljora-badges__item {
  border-left-color: var(--c-border-dark);
}

/* -- Footer on dark ----------------------------------------------------- */
.siljora-footer__brand-name {
  color: var(--c-on-dark);
}

.siljora-footer__heading {
  color: var(--c-on-dark);
}

.siljora-footer__list a,
.siljora-footer__line a {
  color: var(--c-on-dark-muted);
}

.siljora-footer__list a:hover,
.siljora-footer__line a:hover {
  color: var(--c-accent);
}

/* The navbar's sliding underline, on every footer link: 1px champagne,
   growing left to right, 4px below the text.

   Drawn as a background rather than an ::after, the same way as the account
   page's sentence links. These are inline elements, and a background with
   box-decoration-break follows the text if a label wraps on a narrow screen,
   where a pseudo-element would draw one bar across the wrapped shape. The 4px
   of bottom padding is where the line sits; on an inline element it does not
   change the line height, so nothing in the footer moves. */
.siljora-footer__list a,
.siljora-footer__line a {
  padding-bottom: 4px;
  background-image: linear-gradient(var(--c-accent), var(--c-accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: color var(--t-base) var(--ease-out),
    background-size var(--t-base) var(--ease-out);
}

.siljora-footer__list a:hover,
.siljora-footer__list a:focus-visible,
.siljora-footer__line a:hover,
.siljora-footer__line a:focus-visible {
  background-size: 100% 1px;
}

@media (prefers-reduced-motion: reduce) {
  .siljora-footer__list a,
  .siljora-footer__line a {
    transition: none;
  }
}

.siljora-footer__line {
  color: var(--c-on-dark-muted);
}

.siljora-footer__line strong {
  color: var(--c-on-dark);
}

/* Each column gets a fine rule above its heading — an editorial detail that
   reads as intentional rather than decorative. */
.siljora-footer__column .siljora-footer__heading {
  padding-top: var(--space-4);
  border-top: 1px solid var(--c-border-dark);
}

/* -- Astra's copyright bar --------------------------------------------- */
.site-below-footer-wrap,
.ast-footer-copyright,
.ast-footer-copyright p {
  color: var(--c-on-dark-muted);
}

.site-below-footer-wrap {
  border-top: 1px solid var(--c-border-dark);
}

.ast-footer-copyright a {
  color: var(--c-on-dark-muted);
}

.ast-footer-copyright a:hover {
  color: var(--c-accent);
}

@media (max-width: 600px) {
  /* Stacked columns don't need a rule on every heading — it becomes noise. */
  .siljora-footer__column .siljora-footer__heading {
    border-top: 0;
    padding-top: 0;
  }
}

/* ==========================================================================
   Luxury material details
   ========================================================================== */

/* Section rhythm: ivory → cream → ivory → espresso, so the eye has somewhere
   to rest between product moments instead of one flat wash. */
#siljora-featured {
  background-color: var(--c-surface-muted);
  /* Runs edge to edge without 100vw maths: the spread shadow paints past
     the container and clip-path stops it reaching the document scroll
     width, so no horizontal scrollbar appears. */
  box-shadow: 0 0 0 100vmax var(--c-surface-muted);
  clip-path: inset(0 -100vmax);
}

/* Product cards as display cases: a hairline that warms to champagne on
   hover, layered over the existing image zoom rather than replacing it. */
.woocommerce ul.products li.product a img,
.woocommerce ul.products li.product img {
  border: 1px solid var(--c-border-light);
  transition: transform var(--t-slow) var(--ease-out),
    background-color var(--t-slow) var(--ease-out),
    border-color var(--t-base) var(--ease-out);
}

.woocommerce ul.products li.product:hover img {
  border-color: var(--c-accent);
}

/* Price sits in espresso, not grey — it should feel considered, not incidental. */
.woocommerce ul.products li.product .price {
  color: var(--c-text);
}

/* Secondary button: fine border, filling to champagne on hover. Espresso
   label on gold is 7.1:1 — white on gold would be 2.2:1. */
.woocommerce ul.products li.product .button:hover {
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-text);
}

/* Card surfaces get a hairline so every surface in the system is framed the
   same way. The hero viewport is excluded: it is a transparent stage for the
   floating arc, so a border there frames empty space. */
.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__viewport {
  border: 1px solid var(--c-border-light);
}

/* Squared quantity field to match the buttons beside it. */
.woocommerce div.product form.cart .quantity input.qty {
  border-radius: var(--radius-btn);
}

/* Contact form controls follow the same language. */
.siljora-contact-form input[type='text'],
.siljora-contact-form input[type='email'],
.siljora-contact-form textarea {
  border-radius: var(--radius-btn);
  background-color: var(--c-surface);
  border-color: var(--c-border);
}

.siljora-contact-submit {
  border-radius: var(--radius-btn);
  background-color: var(--c-text);
}

.siljora-contact-submit:hover {
  background-color: var(--c-accent-ink);
}

/* Astra paints the footer wrapper, so the copyright bar needs the dark
   treatment at the <footer> level to avoid a pale strip below the band. */
.site-footer,
.site-footer .site-below-footer-wrap {
  background-color: var(--c-dark);
}

/* Smallest phones: pull the arc in so the ghost cards stay fully on screen
   instead of being clipped at the viewport edge. */
@media (max-width: 400px) {
  .siljora-carousel--hero {
    --siljora-arc-x: min(17vw, 62px);
    --siljora-arc-y: 30px;
    --siljora-arc-scale: 0.36;
  }
}

/* The page ground is what the whole palette depends on: it is what makes a
   white product card read as elevated instead of blending in. Astra paints
   it white via `.ast-plain-container` — a class selector, so it outranks
   both `body` and `html body`. Matching the class with the element in front
   wins it back without resorting to !important. */
body.ast-plain-container,
body.ast-page-builder-template,
body.ast-separate-container {
  background-color: var(--c-bg);
}

/* Astra paints the inner header rows solid white, which sat on top of the
   masthead's translucent tint and produced a hard seam against the ivory
   page. Letting the rows go transparent makes the masthead itself the
   surface, so the blur actually reads as frosted glass over the ground. */
.site-header .ast-primary-header-bar,
.site-header .main-header-bar,
.site-header .ast-main-header-wrap,
.site-header .ast-mobile-header-wrap,
.site-header .ast-above-header-bar,
.site-header .ast-below-header-bar {
  background-color: transparent;
}

/* ==========================================================================
   Primary button
   ========================================================================== */

/* Astra underlines every link inside post content
   (.ast-single-post .entry-content a), which outranks the global reset and
   was drawing a line under the button labels. Scoped to our component links
   only — genuine inline links in copy keep their underline, which is the
   accessible default. */
.ast-single-post .entry-content a.siljora-hero-button,
.ast-single-post .entry-content a.siljora-carousel__cta,
.ast-single-post .entry-content a.siljora-collections__card,
.ast-single-post .entry-content .woocommerce a.button,
.entry-content a.siljora-hero-button,
.entry-content a.siljora-carousel__cta,
.entry-content a.siljora-collections__card {
  text-decoration: none;
}

/* A gold fill that wipes in from the left, with the label flipping to
   espresso as it lands — dark-on-champagne reads at 7.1:1, and it looks
   like the metal rather than a coloured rectangle. The existing arrow
   still extends on hover; this layers underneath it. */
.siljora-hero-button,
.siljora-carousel__cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border: 1px solid var(--c-text);
  border-radius: var(--radius-btn);
  transition: color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out);
}

.siljora-hero-button::before,
.siljora-carousel__cta::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--c-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-slow) var(--ease-out);
}

.siljora-hero-button:hover,
.siljora-hero-button:focus-visible,
.siljora-carousel__cta:hover,
.siljora-carousel__cta:focus-visible {
  color: var(--c-text);
  /* Champagne rather than espresso: the ::before wipe paints the same
     colour, so if it ever fails to render the label is still espresso on
     gold instead of espresso on espresso. */
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.siljora-hero-button:hover::before,
.siljora-hero-button:focus-visible::before,
.siljora-carousel__cta:hover::before,
.siljora-carousel__cta:focus-visible::before {
  transform: scaleX(1);
}

/* WooCommerce buttons get the same wipe so every CTA behaves alike. */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

.woocommerce a.button::before,
.woocommerce button.button::before,
.woocommerce input.button::before,
.woocommerce #respond input#submit::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-color: var(--c-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-slow) var(--ease-out);
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover,
.woocommerce ul.products li.product .button:hover {
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-text);
}

.woocommerce a.button:hover::before,
.woocommerce button.button:hover::before,
.woocommerce input.button:hover::before,
.woocommerce #respond input#submit:hover::before {
  transform: scaleX(1);
}

/* The arrow rule on the hero CTA sits above the wipe. */
.siljora-hero-button::after {
  position: relative;
  z-index: 1;
}

/* ==========================================================================
   Account: nav entry + My Account forms
   ========================================================================== */

/* Signed out — a quiet outlined button so it reads as an action without
   competing with the primary nav links. */
.siljora-account-item .menu-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.site-header .siljora-account-item .siljora-account-button {
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-btn);
  line-height: 1;
  padding: 0.8em 1.4em;
  color: var(--c-text);
  transition: color var(--t-base) var(--ease-out),
    background-color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out);
}

/* The nav's shared underline would sit oddly under a bordered button. */
.site-header .siljora-account-item .siljora-account-button::after {
  display: none;
}

/* Astra sets `height: 100%` on direct-child menu links so they fill the
   80px header row. An explicit height outranks align-self, so the outlined
   button has to opt out at matching specificity or it draws a full-height
   box instead of a button. */
.site-header .main-header-menu > .menu-item.siljora-account-item > .siljora-account-button {
  height: auto;
  align-self: center;
}

.site-header .siljora-account-item .siljora-account-button:hover,
.site-header .siljora-account-item .siljora-account-button:focus-visible {
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-text);
}

/* Signed in — name and glyph, matching the cart treatment. */
.siljora-account-icon {
  flex-shrink: 0;
  transition: transform var(--t-base) var(--ease-out);
}

.site-header .siljora-account-item--user .menu-link:hover .siljora-account-icon {
  transform: translateY(-2px);
}

.siljora-account-name {
  max-width: 16ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -- Profile dropdown ---------------------------------------------------- */
/* The saved list, orders and sign-out live behind the profile rather than in
   the nav itself. Beside the cart, "Saved" rendered as a matching icon-and-
   label sibling and the two read as one pair competing for the same slot. */
.siljora-account-item--user {
  position: relative;
}

.site-header .siljora-account-toggle {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
}

/* Same trap, same theme: the profile toggle is a <button> in the header, and
   Astra would paint it blue on click. */
.site-header .siljora-account-toggle:hover,
.site-header .siljora-account-toggle:focus,
.site-header .siljora-account-toggle:focus-visible,
.site-header .siljora-account-toggle:active {
  background: none;
  background-color: transparent;
  border-color: transparent;
  color: inherit;
}

.siljora-account-chevron {
  flex-shrink: 0;
  opacity: 0.7;
  transition: transform var(--t-base) var(--ease-out);
}

.siljora-account-item--user.is-open .siljora-account-chevron {
  transform: rotate(180deg);
}

/* Astra's `.main-navigation ul { position: relative }` (0,1,1) outranks a bare
   class, which left the panel in the flow — opening it pushed the whole header
   apart instead of floating over the page. Qualifying by the item takes this to
   (0,3,0) and settles it by specificity. */
.site-header .siljora-account-item--user > .siljora-account-menu {
  position: absolute;
  top: calc(100% - 12px);
  right: 0;
  z-index: 100;
  min-width: 210px;
  margin: 0;
  padding: var(--space-2) 0;
  list-style: none;
  background-color: var(--c-surface);
  border: 1px solid var(--c-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  text-align: left;
}

.siljora-account-menu__item {
  margin: 0;
  list-style: none;
}

/* A hairline before Sign out, so it is not reached by accident on the way
   to Orders. */
.siljora-account-menu__item--out {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--c-border-light);
}

.site-header .siljora-account-menu__link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  height: auto;
  /* 44px floor, same as the save control: these are one-handed taps in a menu
     that sits under the thumb. */
  min-height: 44px;
  padding: 0.7em var(--space-4);
  color: var(--c-text);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  letter-spacing: 0;
  text-transform: none;
  text-decoration: none;
  line-height: 1.3;
  transition: background-color var(--t-fast) var(--ease-out),
    color var(--t-fast) var(--ease-out);
}

/* Astra recolours nav links on hover and focus, so both states restate their
   own colours rather than inheriting a white-on-white surprise. */
.site-header .siljora-account-menu__link:hover,
.site-header .siljora-account-menu__link:focus-visible {
  background-color: var(--c-surface-muted);
  color: var(--c-text);
}

.site-header .siljora-account-menu__link::after {
  display: none;
}

.siljora-account-menu__icon {
  flex-shrink: 0;
}

/* The count sits at the far end of its row rather than hard against the word. */
.siljora-account-menu__link .siljora-wish-count {
  margin-left: auto;
}

@media (max-width: 921px) {
  /* Stacked mobile menu: let the button sit inline rather than stretch. */
  .siljora-account-item .menu-link {
    justify-content: flex-start;
  }

  .siljora-account-name {
    max-width: none;
  }

  /* The profile toggle is a button, and sat centred while every link row sat
     left, so the stacked menu read as two different lists. Astra forces `display:
     block` here, which leaves justify-content inert and hands the button its
     UA default of text-align:center — so the fix has to restore the flex box
     as well as the alignment. */
  .site-header .main-header-menu .siljora-account-toggle {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
  }

  /* No room to float a panel over a stacked menu, so it expands in place. */
  .site-header .siljora-account-item--user > .siljora-account-menu {
    position: static;
    min-width: 0;
    margin: var(--space-2) 0 var(--space-2) var(--space-5);
    box-shadow: none;
    background-color: transparent;
    border: 0;
    border-left: 1px solid var(--c-border-light);
    border-radius: 0;
    padding: 0;
  }

  .site-header .siljora-account-menu__link {
    padding-left: var(--space-4);
  }
}

/* -- My Account: login + register ---------------------------------------- */
.woocommerce-account .woocommerce {
  max-width: var(--container);
  margin-inline: auto;
}


.woocommerce-account h2 {
  font-family: var(--font-display);
  font-size: 1.6rem;
  letter-spacing: 0.01em;
  margin: 0 0 var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--c-border);
}

/* Astra borders these via `body .woocommerce form.login` (0,2,2), which
   outranked a plain `.woocommerce form.woocommerce-form-login` and drew a
   second box inside our card. Doubling up the class matches its weight
   and then some. */
body .woocommerce form.login.woocommerce-form-login,
body .woocommerce form.register.woocommerce-form-register {
  border: 0;
  padding: 0;
  margin: 0;
  border-radius: 0;
}

.woocommerce form .form-row label {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  margin-bottom: var(--space-2);
}

.woocommerce form .form-row input.input-text,
.woocommerce-account input[type='text'],
.woocommerce-account input[type='email'],
.woocommerce-account input[type='password'] {
  width: 100%;
  background-color: var(--c-bg);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm);
  padding: 0.9em 1em;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--c-text);
  transition: border-color var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out);
}

.woocommerce form .form-row input.input-text:focus,
.woocommerce-account input[type='text']:focus,
.woocommerce-account input[type='email']:focus,
.woocommerce-account input[type='password']:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px rgba(192, 160, 98, 0.18);
}

.woocommerce-account .woocommerce-form-login__rememberme,
.woocommerce-account .woocommerce-privacy-policy-text {
  font-size: 0.9rem;
  color: var(--c-text-muted);
}

.woocommerce-account .woocommerce-LostPassword a {
  color: var(--c-text-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--c-border-strong);
  transition: color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out);
}

.woocommerce-account .woocommerce-LostPassword a:hover {
  color: var(--c-text);
  border-color: var(--c-accent);
}

/* Signed-in dashboard navigation. */
.woocommerce-account .woocommerce-MyAccount-navigation ul {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background-color: var(--c-surface);
}

.woocommerce-account .woocommerce-MyAccount-navigation li + li {
  border-top: 1px solid var(--c-border);
}

/* Each row keeps its full-width tint and click area, but the navbar's
   growing gold underline sits under the WORD, not across the row.

   The link is 350px wide and the label 47-108px, so an underline sized to the
   link would span the whole row. The link therefore shrinks to its text
   (width: fit-content), and a transparent ::before stretched over the <li>
   keeps the entire row clickable. The tint moves to the <li> for the same
   reason: on the shrunken link it would only colour the word. */
.woocommerce-account .woocommerce-MyAccount-navigation li {
  position: relative;
  transition: background-color var(--t-base) var(--ease-out);
}

.woocommerce-account .woocommerce-MyAccount-navigation li:has(> a:hover),
.woocommerce-account .woocommerce-MyAccount-navigation li.is-active {
  background-color: var(--c-surface-muted);
}

.woocommerce-account .woocommerce-MyAccount-navigation a {
  display: block;
  width: fit-content;
  padding: 0.9em 1.25em;
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  color: var(--c-text-muted);
  text-decoration: none;
  /* The navbar line: 1px champagne, growing left to right, 4px below the
     text. Drawn as a background sized to the content box, which on a
     fit-content link is exactly the label. */
  background-image: linear-gradient(var(--c-accent), var(--c-accent));
  background-origin: content-box;
  background-repeat: no-repeat;
  background-position: 0 calc(100% + 4px);
  background-size: 0% 1px;
  transition: color var(--t-base) var(--ease-out),
    background-size var(--t-base) var(--ease-out);
}

/* The whole row is the hit area. */
.woocommerce-account .woocommerce-MyAccount-navigation a::before {
  content: '';
  position: absolute;
  inset: 0;
}

.woocommerce-account .woocommerce-MyAccount-navigation a:hover,
.woocommerce-account .woocommerce-MyAccount-navigation a:focus-visible,
.woocommerce-account .woocommerce-MyAccount-navigation .is-active a {
  color: var(--c-text);
  background-size: 100% 1px;
}

/* The link itself stays transparent in every state. WooCommerce paints the
   current page's link #fbfbfb via `body .woocommerce-MyAccount-navigation-link
   .is-active a` (0,3,2); on a word-width link that showed as a pale box behind
   "Dashboard" inside the tinted row. This is (0,4,2). */
.woocommerce-account .woocommerce-MyAccount-navigation .woocommerce-MyAccount-navigation-link a,
.woocommerce-account .woocommerce-MyAccount-navigation .woocommerce-MyAccount-navigation-link.is-active a {
  background-color: transparent;
}

/* Focus ring on the row, not the shrunken word, so keyboard users see the
   same target a mouse user clicks. Astra draws its own dotted ring with
   `.woocommerce .woocommerce-MyAccount-navigation ul li a:focus-visible`
   (0,3,3), which produced a second outline around the word; this is (0,4,3).
   Plain :focus is cleared too, so a mouse click shows no ring at all, which is
   what :focus-visible exists to allow. */
.woocommerce-account .woocommerce .woocommerce-MyAccount-navigation ul li a:focus,
.woocommerce-account .woocommerce .woocommerce-MyAccount-navigation ul li a:focus-visible {
  outline: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation li:has(> a:focus-visible) {
  box-shadow: inset 0 0 0 2px var(--c-accent);
}

/* Links inside the dashboard's sentences get the same growing line. A
   background rather than a pseudo-element, because these are inline and
   "edit your password and account details" wraps onto a second line on
   narrower screens: box-decoration-break carries the line onto each line
   box, where an ::after would draw one bar across the wrapped shape. */
.woocommerce-account .woocommerce-MyAccount-content p a {
  text-decoration: none;
  padding-bottom: 4px;
  background-image: linear-gradient(var(--c-accent), var(--c-accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size var(--t-base) var(--ease-out);
}

/* Text stays dark on hover, as in the navbar. The site-wide `a:hover` turns
   links rose gold (#c2988c), which is 2.27:1 on the ivory page — under the
   4.5:1 body text needs, at exactly the moment someone is aiming at it. */
.woocommerce-account .woocommerce-MyAccount-content p a:hover,
.woocommerce-account .woocommerce-MyAccount-content p a:focus-visible {
  color: var(--c-text);
  background-size: 100% 1px;
}

@media (prefers-reduced-motion: reduce) {
  .woocommerce-account .woocommerce-MyAccount-navigation a,
  .woocommerce-account .woocommerce-MyAccount-content p a {
    transition: none;
  }
}

/* The two added fields sit full width like the stock ones. */
.woocommerce form .form-row-wide {
  width: 100%;
  float: none;
}

/* ==========================================================================
   About page
   ========================================================================== */
.siljora-about-lede {
  max-width: 44ch;
}

.siljora-about-statement {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  font-style: italic;
  line-height: 1.16;
  color: var(--c-text);
  margin: var(--space-3) 0 var(--space-5);
}

.siljora-about-lede-text {
  font-size: 1.08rem;
  font-weight: 300;
  color: var(--c-text-muted);
  margin: 0;
}

/* -- Alternating image / copy bands -- */
.siljora-about-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}

.siljora-about-split--reverse .siljora-about-media {
  order: 2;
}

.siljora-about-media {
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--c-surface-muted);
}

.siljora-about-img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  transition: transform 1.2s var(--ease-out);
}

.siljora-about-media:hover .siljora-about-img {
  transform: scale(1.03);
}

/* Small editorial numerals, the kind a print piece would use. */
.siljora-about-index {
  display: block;
  font-family: var(--font-display);
  font-size: 0.9rem;
  letter-spacing: 0.22em;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-3);
}

.siljora-about-heading {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.4vw, 1.9rem);
  line-height: 1.2;
  margin: 0 0 var(--space-4);
  color: var(--c-text);
}

.siljora-about-copy p {
  color: var(--c-text-muted);
  font-weight: 300;
  margin: 0 0 var(--space-4);
  max-width: 46ch;
}

.siljora-about-copy .siljora-hero-button {
  margin-top: var(--space-3);
}

/* -- Three pillars -- */
.siljora-about-pillars {
  background-color: var(--c-surface-muted);
}

.siljora-about-pillar-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
}

.siljora-about-pillar {
  padding-top: var(--space-4);
  border-top: 1px solid var(--c-border-strong);
}

.siljora-about-pillar p {
  color: var(--c-text-muted);
  font-weight: 300;
  margin: 0;
}

/* -- Pull quote on espresso -- */
.siljora-about-quote {
  background-color: var(--c-text);
  padding: clamp(4rem, 9vw, 7rem) var(--space-5);
}

.siljora-about-quote-inner {
  max-width: 40ch;
  margin-inline: auto;
  text-align: center;
}

.siljora-about-quote-text {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
  line-height: 1.35;
  color: var(--c-text-inverse);
  margin: 0;
  border: 0;
  padding: 0;
  quotes: none;
}

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

  /* Image first in both bands once stacked — alternating order only reads
     as intentional side by side. */
  .siljora-about-split--reverse .siljora-about-media {
    order: -1;
  }

  .siljora-about-pillar-grid {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }

  .siljora-about-img {
    aspect-ratio: 3 / 2;
  }
}

/* Full-bleed tinted bands inside the container.
   The page content is boxed by Astra's ~1200px container, so a tinted
   section stops short of the viewport edge and reads as a mistake next to
   the full-width footer. Painting the colour with an oversized box-shadow
   (clipped vertically) extends it edge to edge without 100vw maths —
   box-shadow doesn't contribute to the scroll area, so it can't reintroduce
   the horizontal overflow we hit earlier. */
.siljora-about-pillars,
.siljora-about-quote {
  clip-path: inset(0 -100vmax);
}

.siljora-about-pillars {
  box-shadow: 0 0 0 100vmax var(--c-surface-muted);
}

.siljora-about-quote {
  box-shadow: 0 0 0 100vmax var(--c-text);
}

/* ==========================================================================
   Contact page
   ========================================================================== */
.siljora-contact-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}

.siljora-contact-aside {
  position: sticky;
  top: calc(var(--space-8) + 60px);
}

.siljora-contact-details {
  margin: var(--space-5) 0 var(--space-6);
}

.siljora-contact-detail + .siljora-contact-detail {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--c-border);
}

.siljora-contact-detail-label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-2);
}

.siljora-contact-detail-value {
  display: block;
  font-size: 1.02rem;
  font-weight: 300;
  color: var(--c-text);
  text-decoration: none;
  transition: color var(--t-base) var(--ease-out);
}

a.siljora-contact-detail-value:hover {
  color: var(--c-accent-ink);
}

.siljora-contact-note {
  font-size: 0.92rem;
  font-weight: 300;
  color: var(--c-text-muted);
  margin: 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--c-border);
}

/* -- Form -- */
.siljora-contact-formwrap {
  background-color: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 4vw, 3rem);
}

.siljora-contact-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.siljora-contact-field {
  margin-bottom: var(--space-5);
}

.siljora-contact-form label {
  display: block;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  margin-bottom: var(--space-2);
}

.siljora-contact-form input[type='text'],
.siljora-contact-form input[type='email'],
.siljora-contact-form textarea {
  width: 100%;
  background-color: var(--c-bg);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm);
  padding: 0.85em 1em;
  font-family: var(--font-body);
  font-size: 0.98rem;
  color: var(--c-text);
  transition: border-color var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out);
}

.siljora-contact-form input[type='text']:focus,
.siljora-contact-form input[type='email']:focus,
.siljora-contact-form textarea:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px rgba(192, 160, 98, 0.18);
}

.siljora-contact-form textarea {
  resize: vertical;
  min-height: 150px;
}

/* Hidden from people, visible to bots. */
.siljora-contact-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.siljora-contact-submit {
  background-color: var(--c-text);
  color: var(--c-text-inverse);
  border: 1px solid var(--c-text);
  border-radius: var(--radius-btn);
  padding: 0.95em 2.4em;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out);
}

.siljora-contact-submit:hover {
  background-color: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-text);
}

.siljora-contact-notice {
  border-radius: var(--radius-sm);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
  font-size: 0.95rem;
  border-left: 3px solid;
}

.siljora-contact-notice--success {
  background-color: rgba(96, 122, 82, 0.1);
  border-left-color: #5f7a52;
  color: #3d5236;
}

.siljora-contact-notice--error {
  background-color: rgba(158, 76, 62, 0.09);
  border-left-color: #9e4c3e;
  color: #7d3a2e;
}

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

  .siljora-contact-aside {
    position: static;
  }
}

@media (max-width: 600px) {
  .siljora-contact-row {
    grid-template-columns: 1fr;
    gap: 0;
  }
}

/* The intro sits directly above the form grid, so its bottom padding and
   the grid's top padding were stacking into a dead band. */
.siljora-contact-intro {
  padding-bottom: 0;
}

/* ==========================================================================
   Policy documents (terms, refund, privacy, returns …)
   ========================================================================== */
.siljora-doc-header {
  max-width: 46ch;
  margin-bottom: var(--space-7);
}

.siljora-doc-title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.2vw, 3rem);
  font-style: italic;
  line-height: 1.15;
  color: var(--c-text);
  margin: var(--space-3) 0 var(--space-4);
}

.siljora-doc-meta {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin: 0 0 var(--space-4);
}

.siljora-doc-summary {
  font-size: 1.05rem;
  font-weight: 300;
  color: var(--c-text-muted);
  margin: 0;
}

.siljora-doc-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 4.5rem);
  align-items: start;
}

/* -- Auto-generated index (see js/doc-toc.js) -- */
.siljora-doc-toc {
  position: sticky;
  top: calc(80px + var(--space-5));
  border-left: 1px solid var(--c-border);
  padding-left: var(--space-4);
}

.siljora-doc-toc-label {
  display: block;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  margin-bottom: var(--space-3);
}

.siljora-doc-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.siljora-doc-toc-list li + li {
  margin-top: var(--space-2);
}

.siljora-doc-toc-list a {
  display: block;
  font-size: 0.88rem;
  font-weight: 300;
  line-height: 1.4;
  color: var(--c-text-muted);
  text-decoration: none;
  transition: color var(--t-base) var(--ease-out);
}

.siljora-doc-toc-list a:hover,
.siljora-doc-toc-list a.is-current {
  color: var(--c-text);
}

.siljora-doc-toc-list a.is-current {
  font-weight: 400;
}

/* -- Document body: set for reading, not for decoration -- */
.siljora-doc-body {
  max-width: 68ch;
}

.siljora-doc-body--full {
  max-width: 72ch;
  margin-inline: auto;
}

.siljora-doc-body h2 {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.2vw, 1.6rem);
  line-height: 1.25;
  color: var(--c-text);
  margin: var(--space-7) 0 var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--c-border);
  /* Clears the sticky header when jumped to from the index. */
  scroll-margin-top: 110px;
}

.siljora-doc-body h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.siljora-doc-body h3 {
  font-family: var(--font-body);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-text);
  margin: var(--space-5) 0 var(--space-3);
}

.siljora-doc-body p,
.siljora-doc-body li {
  font-weight: 300;
  line-height: 1.75;
  color: var(--c-text-muted);
}

.siljora-doc-body p {
  margin: 0 0 var(--space-4);
}

.siljora-doc-body ul,
.siljora-doc-body ol {
  margin: 0 0 var(--space-4);
  padding-left: 1.25rem;
}

.siljora-doc-body li + li {
  margin-top: var(--space-2);
}

.siljora-doc-body a {
  color: var(--c-text);
  text-decoration: none;
  border-bottom: 1px solid var(--c-accent);
  transition: color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out);
}

.siljora-doc-body a:hover {
  color: var(--c-accent-ink);
  border-color: var(--c-accent-ink);
}

/* Placeholder marker, so unfinished clauses are obvious while drafting. */
.siljora-doc-body .siljora-doc-draft {
  display: inline-block;
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-accent-ink);
  background-color: rgba(192, 160, 98, 0.12);
  border-radius: var(--radius-sm);
  padding: 0.25em 0.7em;
  margin-bottom: var(--space-3);
}

@media (max-width: 900px) {
  .siljora-doc-layout {
    grid-template-columns: 1fr;
  }

  .siljora-doc-toc {
    position: static;
    border-left: 0;
    border-bottom: 1px solid var(--c-border);
    padding-left: 0;
    padding-bottom: var(--space-5);
    margin-bottom: var(--space-5);
  }

  .siljora-doc-body {
    max-width: none;
  }
}

/* ==========================================================================
   Track your order
   ========================================================================== */
.siljora-track-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
  margin-top: var(--space-7);
}

.siljora-track-form {
  background-color: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  padding: clamp(1.75rem, 4vw, 2.75rem);
}

.siljora-track-form form.track_order p:first-child {
  margin-top: 0;
}

.siljora-track-form .form-row-first,
.siljora-track-form .form-row-last {
  width: 100%;
  float: none;
  margin-bottom: var(--space-5);
}

.siljora-track-form label {
  display: block;
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-muted);
  margin-bottom: var(--space-2);
}

.siljora-track-form input[type='text'],
.siljora-track-form input[type='email'] {
  width: 100%;
  background-color: var(--c-bg);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-sm);
  padding: 0.85em 1em;
  font-family: var(--font-body);
  font-size: 0.98rem;
  color: var(--c-text);
  transition: border-color var(--t-base) var(--ease-out),
    box-shadow var(--t-base) var(--ease-out);
}

.siljora-track-form input[type='text']:focus,
.siljora-track-form input[type='email']:focus {
  outline: none;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px rgba(192, 160, 98, 0.18);
}

/* -- Status key -- */
.siljora-track-status {
  margin: var(--space-5) 0 var(--space-6);
}

.siljora-track-status dt {
  font-size: 0.76rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-2);
}

.siljora-track-status dd {
  margin: 0 0 var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--c-border);
  font-weight: 300;
  line-height: 1.65;
  color: var(--c-text-muted);
}

.siljora-track-status dd:last-child {
  border-bottom: 0;
  margin-bottom: 0;
}

.siljora-track-help {
  font-size: 0.92rem;
  font-weight: 300;
  color: var(--c-text-muted);
  margin: 0;
}

.siljora-track-aside a,
.siljora-track-help a {
  color: var(--c-text);
  text-decoration: none;
  border-bottom: 1px solid var(--c-accent);
  transition: color var(--t-base) var(--ease-out);
}

.siljora-track-aside a:hover {
  color: var(--c-accent-ink);
}

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

/* Astra underlines every link inside .entry-content at a higher specificity
   than a single component class, which put a line under each index entry
   and doubled up with the gold rule on body links. */
.ast-single-post .entry-content .siljora-doc-toc-list a,
.ast-single-post .entry-content .siljora-doc-body a,
.ast-single-post .entry-content .siljora-track-aside a,
.ast-single-post .entry-content .siljora-contact-detail-value {
  text-decoration: none;
}

/* Opening spread: the lede sits beside an image rather than trailing off
   into empty space on the right. Slightly text-weighted so the statement
   still leads. */
.siljora-about-grid--intro {
  grid-template-columns: 1.1fr 0.9fr;
  align-items: center;
}

.siljora-about-grid--intro .siljora-about-lede {
  max-width: 42ch;
}

.siljora-about-grid--intro .siljora-about-img {
  aspect-ratio: 4 / 5;
}

@media (max-width: 900px) {
  .siljora-about-grid--intro {
    grid-template-columns: 1fr;
  }

  /* Statement first on a phone; the image supports it rather than
     pushing it below the fold. */
  .siljora-about-grid--intro .siljora-about-media {
    order: 2;
  }

  .siljora-about-grid--intro .siljora-about-img {
    aspect-ratio: 3 / 2;
  }
}

/* -- Cart count badge ---------------------------------------------------- */
.siljora-cart-item .menu-link {
  position: relative;
}

/* In the phone menu the bag sits beside a visible "Cart". Astra forces mobile
   menu links to display:block, which put the bag on the text baseline so it
   rode higher than the word and pushed its badge toward the row above.
   A flex row centres the two against each other.

   Astra's `.ast-header-break-point .main-navigation ul .menu-item .menu-link`
   (0,4,1) set the display on this link; the selector below is (0,5,1). */
@media (max-width: 921px) {
  .ast-header-break-point .site-header .main-navigation ul .siljora-cart-item > .menu-link {
    display: flex;
    align-items: center;
    gap: 0.9rem;
  }
}

/* A dark disc overlapping the bag's top-right corner. The ring in the page
   colour separates it from the icon's outline where the two meet, so the
   number stays legible instead of merging into the stroke. It grows into a
   pill for two digits and caps at "99+" (see siljora_cart_count_html()). */
.siljora-cart-count {
  position: absolute;
  top: -8px;
  right: -11px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  margin: 0;
  border-radius: 999px;
  background-color: var(--c-text);
  color: var(--c-text-inverse);
  box-shadow: 0 0 0 2px var(--c-bg);
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
  pointer-events: none;
}

/* Visually hidden, still read aloud. */
.siljora-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* -- Cart: quantity changes apply themselves ----------------------------- */
/* The button stays in the DOM because WooCommerce's update handler only
   fires when `update_cart` is present in the POST; the JS names it as the
   form's submitter (see js/cart-auto-update.js), which works regardless of
   whether it's visible.
   !important is deliberate here: WooCommerce sizes this button through
   ID-based selectors (`#content table.cart .button`) that outrank any
   sensible class selector, and there is no state in which we want it shown. */
.woocommerce-cart-form [name='update_cart'] {
  display: none !important;
}

/* Quiet feedback while the updated cart loads. */
.woocommerce-cart-form.is-updating {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease-out);
}

/* ==========================================================================
   Category cards: a "Shop" cue replaces the product count
   ========================================================================== */
.siljora-collections__cue {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-family: var(--font-body);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out);
}

.siljora-collections__card:hover .siljora-collections__cue,
.siljora-collections__card:focus-visible .siljora-collections__cue {
  opacity: 1;
  transform: translateY(0);
}

.siljora-collections__arrow {
  transition: transform var(--t-base) var(--ease-out);
}

.siljora-collections__card:hover .siljora-collections__arrow {
  transform: translateX(4px);
}

.siljora-collections__name {
  transition: transform var(--t-base) var(--ease-out);
}

.siljora-collections__card:hover .siljora-collections__name {
  transform: translateY(-2px);
}

/* ==========================================================================
   The Siljorah Promise
   ========================================================================== */
.siljora-badges__head {
  max-width: var(--container);
  margin: 0 auto var(--space-6);
  text-align: center;
}

.siljora-badges__inner {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 1100px) {
  .siljora-badges__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-6) 0;
  }

  /* Two-up: the rule belongs between columns, not between rows. */
  .siljora-badges__item + .siljora-badges__item {
    border-left: 0;
  }

  .siljora-badges__item:nth-child(even) {
    border-left: 1px solid var(--c-border);
  }
}

/* ==========================================================================
   Made With Intention
   ========================================================================== */
.siljora-story__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}

.siljora-story__media {
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--c-surface-muted);
}

.siljora-story__img {
  display: block;
  width: 100%;
  aspect-ratio: 5 / 4;
  object-fit: cover;
  transition: transform 1.2s var(--ease-out);
}

.siljora-story__media:hover .siljora-story__img {
  transform: scale(1.03);
}

.siljora-story__title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.7rem, 3.2vw, 2.5rem);
  line-height: 1.18;
  color: var(--c-text);
  margin: var(--space-3) 0 var(--space-5);
  max-width: 18ch;
}

.siljora-story__copy p {
  font-weight: 300;
  line-height: 1.75;
  color: var(--c-text-muted);
  margin: 0 0 var(--space-4);
  max-width: 46ch;
}

.siljora-story__copy .siljora-hero-button {
  margin-top: var(--space-3);
}

/* ==========================================================================
   Reviews
   ========================================================================== */
.siljora-reviews__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}

.siljora-reviews__item {
  margin: 0;
  text-align: center;
  padding: 0 var(--space-4);
}

.siljora-reviews__stars {
  display: block;
  color: var(--c-accent);
  letter-spacing: 0.2em;
  margin-bottom: var(--space-4);
}

.siljora-reviews__text {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.15rem;
  line-height: 1.6;
  color: var(--c-text);
  border: 0;
  margin: 0 0 var(--space-4);
  padding: 0;
}

.siljora-reviews__who {
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text-muted);
}


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

  .siljora-story__img {
    aspect-ratio: 3 / 2;
  }
}

@media (max-width: 600px) {
  .siljora-badges__inner {
    grid-template-columns: 1fr;
  }

  .siljora-badges__item:nth-child(even) {
    border-left: 0;
  }
}

/* The Promise now sits inside page content (it used to render full-width via
   a footer hook), so it needs the same edge-to-edge treatment as the About
   bands: an oversized box-shadow clipped vertically. Avoids 100vw, which
   reintroduces horizontal scroll once a scrollbar is present. */
/* The Promise has moved from the pre-footer slot into mid-page, so it can no
   longer be part of the continuous dark band that anchors the footer. Three
   separate dark zones (promise, newsletter, footer) would fight each other;
   a soft champagne band gives the value contrast without the weight.
   The spill colour must match the band's own background, and the inset gold
   hairline is carried in the same declaration so it isn't overwritten. */
.siljora-badges {
  background-color: var(--c-surface-muted);
  color: var(--c-text-muted);
  border-top: 1px solid var(--c-border);
  clip-path: inset(0 -100vmax);
  box-shadow: inset 0 1px 0 rgba(192, 160, 98, 0.2),
    0 0 0 100vmax var(--c-surface-muted);
}

.siljora-badges__icon {
  color: var(--c-accent-ink);
}

.siljora-badges__title {
  color: var(--c-text);
}

.siljora-badges__text {
  color: var(--c-text-muted);
}

.siljora-badges__item + .siljora-badges__item {
  border-left-color: var(--c-border);
}

/* Astra underlines links inside .entry-content at higher specificity than a
   component class; category cards are whole-card links, so the line reads as
   a mistake rather than affordance. */
.ast-single-post .entry-content .siljora-collections__card,
.ast-single-post .entry-content .siljora-story__copy a.siljora-hero-button {
  text-decoration: none;
}

/* ==========================================================================
   Product card — shared by New Arrivals and Complete the Look
   ========================================================================== */
.siljora-pcard {
  display: block;
  color: inherit;
  text-decoration: none;
}

.siljora-pcard__media {
  display: block;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--c-surface-muted);
  margin-bottom: var(--space-4);
}

/* Fixed ratio with contain, not cover: these are cut-out product shots and
   cropping one would clip the piece itself. */
.siljora-pcard__img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  padding: var(--space-5);
  transition: transform 0.9s var(--ease-out);
}

.siljora-pcard:hover .siljora-pcard__img,
.siljora-pcard:focus-visible .siljora-pcard__img {
  transform: scale(1.05);
}

.siljora-pcard__body {
  display: block;
  text-align: center;
}

.siljora-pcard__cat {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-2);
}

.siljora-pcard__name {
  display: block;
  font-family: var(--font-display);
  font-size: 1.15rem;
  line-height: var(--lh-heading);
  color: var(--c-text);
  margin-bottom: var(--space-2);
  transition: color var(--t-base) var(--ease-out);
}

.siljora-pcard:hover .siljora-pcard__name {
  color: var(--c-accent-ink);
}

.siljora-pcard__price {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--c-text-muted);
}

.siljora-pcard__price del {
  opacity: 0.55;
  margin-right: var(--space-2);
}

/* ==========================================================================
   New Arrivals
   ========================================================================== */
.siljora-arrivals__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

.siljora-arrivals__foot,
.siljora-look__foot,
.siljora-instagram__foot {
  text-align: center;
  margin-top: var(--space-6);
}

/* ==========================================================================
   Shop by Occasion
   ========================================================================== */
.siljora-occasions__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.siljora-occasions__card {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-md);
  background-color: var(--c-surface-muted);
  color: var(--c-on-dark);
  text-decoration: none;
  min-height: 22rem;
  isolation: isolate;
}

.siljora-occasions__media {
  position: absolute;
  inset: 0;
  display: block;
}

.siljora-occasions__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease-out);
}

.siljora-occasions__card:hover .siljora-occasions__img,
.siljora-occasions__card:focus-visible .siljora-occasions__img {
  transform: scale(1.06);
}

/* Scrim sits above the image but below the copy, so the caption stays
   readable whatever the photograph behind it is doing. */
.siljora-occasions__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Weighted hard toward the bottom: these are bright cream-silk shots, and
     a lighter scrim measured 2.0:1 behind the caption. This holds the copy
     zone near rgb(44,40,37) whatever the photograph is doing. */
  background: linear-gradient(
    to top,
    rgba(23, 18, 15, 0.96) 0%,
    rgba(23, 18, 15, 0.9) 30%,
    rgba(23, 18, 15, 0.66) 55%,
    rgba(23, 18, 15, 0.28) 78%,
    rgba(23, 18, 15, 0.06) 100%
  );
}

.siljora-occasions__body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
  min-height: 22rem;
  padding: var(--space-6);
  text-align: left;
}

.siljora-occasions__title {
  display: block;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.4rem;
  line-height: var(--lh-heading);
  color: var(--c-text-inverse);
  margin-bottom: var(--space-2);
  transition: transform var(--t-base) var(--ease-out);
}

.siljora-occasions__card:hover .siljora-occasions__title {
  transform: translateY(-2px);
}

.siljora-occasions__text {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 300;
  line-height: var(--lh-body);
  /* Not --c-on-dark-muted: over a photograph that tone measured 2.0:1.
     This sits near 10:1 against the scrimmed backdrop. */
  color: rgba(243, 236, 226, 0.88);
}

.siljora-occasions__cue {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-text-inverse);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out);
}

.siljora-occasions__card:hover .siljora-occasions__cue,
.siljora-occasions__card:focus-visible .siljora-occasions__cue {
  opacity: 1;
  transform: translateY(0);
}

.siljora-occasions__arrow {
  transition: transform var(--t-base) var(--ease-out);
}

.siljora-occasions__card:hover .siljora-occasions__arrow {
  transform: translateX(4px);
}

/* Touch devices get no hover, so the cue would never appear. */
@media (hover: none) {
  .siljora-occasions__cue {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   Complete the Look
   ========================================================================== */
.siljora-look {
  background-color: var(--c-surface-muted);
  clip-path: inset(0 -100vmax);
  box-shadow: 0 0 0 100vmax var(--c-surface-muted);
}

.siljora-look__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}

.siljora-look .siljora-pcard__media {
  background-color: var(--c-surface);
}

.siljora-look__foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
}

.siljora-look__total {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin: 0;
}

.siljora-look__total-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

.siljora-look__total-value {
  font-family: var(--font-display);
  font-size: 1.4rem;
  color: var(--c-text);
}

/* ==========================================================================
   Instagram
   ========================================================================== */
.siljora-instagram__grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-3);
}

.siljora-instagram__tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background-color: var(--c-surface-muted);
  text-decoration: none;
}

.siljora-instagram__img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: transform 0.9s var(--ease-out);
}

.siljora-instagram__tile:hover .siljora-instagram__img,
.siljora-instagram__tile:focus-visible .siljora-instagram__img {
  transform: scale(1.07);
}

.siljora-instagram__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(23, 18, 15, 0.42);
  color: var(--c-text-inverse);
  opacity: 0;
  transition: opacity var(--t-base) var(--ease-out);
}

.siljora-instagram__tile:hover .siljora-instagram__overlay,
.siljora-instagram__tile:focus-visible .siljora-instagram__overlay {
  opacity: 1;
}

/* ==========================================================================
   Footer social row
   ========================================================================== */
.siljora-footer-social {
  padding: 0 var(--gutter) var(--space-7);
}

.siljora-footer-social__inner {
  max-width: var(--container);
  margin: 0 auto;
  display: flex;
  justify-content: center;
  gap: var(--space-4);
}

.siljora-footer-social__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  /* This row sits inside the espresso footer, so it needs the on-dark
     tokens: --c-text-muted measured 2.8:1 here and --c-border was
     invisible against it. */
  border: 1px solid rgba(243, 236, 226, 0.4);
  border-radius: var(--radius-pill);
  color: var(--c-on-dark-muted);
  text-decoration: none;
  transition: color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out);
}

.siljora-footer-social__link:hover,
.siljora-footer-social__link:focus-visible {
  color: var(--c-accent);
  border-color: var(--c-accent);
  transform: translateY(-2px);
}

/* Astra underlines every link inside .entry-content; these are cards and
   tiles, not body copy. Matches the scoping used for the journal and
   collections cards above. */
.ast-single-post .entry-content .siljora-pcard,
.ast-single-post .entry-content .siljora-occasions__card,
.ast-single-post .entry-content .siljora-instagram__tile,
.ast-single-post .entry-content .siljora-arrivals__foot a.siljora-hero-button,
.ast-single-post .entry-content .siljora-look__foot a.siljora-hero-button,
.ast-single-post .entry-content .siljora-instagram__foot a.siljora-hero-button {
  text-decoration: none;
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1100px) {
  .siljora-arrivals__grid,
  .siljora-occasions__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .siljora-instagram__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 900px) {
  .siljora-look__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* An odd item left alone in a two-up grid looks like a mistake; let the
     last one span the full row instead. */
  .siljora-look__grid > .siljora-pcard:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    max-width: 22rem;
    margin-inline: auto;
  }

  .siljora-occasions__card,
  .siljora-occasions__body {
    min-height: 18rem;
  }
}

@media (max-width: 600px) {
  .siljora-arrivals__grid,
  .siljora-occasions__grid,
  .siljora-look__grid {
    grid-template-columns: 1fr;
  }

  .siljora-look__grid > .siljora-pcard:last-child:nth-child(odd) {
    max-width: none;
  }

  .siljora-instagram__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .siljora-look__total {
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .siljora-pcard__img,
  .siljora-occasions__img,
  .siljora-instagram__img,
  .siljora-occasions__title,
  .siljora-occasions__cue,
  .siljora-occasions__arrow,
  .siljora-footer-social__link {
    transition: none;
  }

  .siljora-pcard:hover .siljora-pcard__img,
  .siljora-occasions__card:hover .siljora-occasions__img,
  .siljora-instagram__tile:hover .siljora-instagram__img,
  .siljora-footer-social__link:hover {
    transform: none;
  }
}

/* ==========================================================================
   Image fitting: photographs vs cut-outs
   ==========================================================================
   The catalogue mixes pieces shot on silk, which carry their own background,
   with pieces cut out onto transparency. The base rules above use contain,
   which is the safe default — it never crops the jewellery — but it letterboxes
   a photograph inside the card and leaves a band of card colour around it.

   Images are classified server-side (inc/image-fit.php) by actual rendered
   transparency, so a photograph fills its frame edge to edge while a cut-out
   keeps the padded well it needs. Only the photo case is overridden here: if
   detection ever fails, the image falls back to contain and is framed oddly
   rather than cropped. */
.siljora-pcard__img.siljora-fit-photo,
.woocommerce ul.products li.product a img.siljora-fit-photo,
.woocommerce ul.products li.product img.siljora-fit-photo {
  object-fit: cover;
  object-position: center;
  padding: 0;
}

/* ==========================================================================
   Empty states
   ==========================================================================
   A category the shop intends to stock is shown even while it holds nothing,
   so both ends of that journey need to read as deliberate: the card says the
   range is coming, and the archive it opens explains itself rather than
   showing a bare "no products found" notice. */
.siljora-collections__cue--soon {
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  padding: 0.35em 0.9em;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* The arrow is the affordance that says "there are pieces through here", so
   an empty card must not borrow it. */
.siljora-collections__card.is-empty .siljora-collections__arrow {
  display: none;
}

.siljora-empty {
  max-width: 34rem;
  margin: clamp(2rem, 6vw, 4.5rem) auto;
  padding: clamp(2rem, 5vw, 3.5rem) var(--space-5);
  text-align: center;
}

.siljora-empty__eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--c-accent-ink);
  margin-bottom: var(--space-4);
}

.siljora-empty__title {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  line-height: 1.25;
  color: var(--c-text);
  margin: 0 0 var(--space-4);
}

.siljora-empty__text {
  font-weight: 300;
  line-height: 1.75;
  color: var(--c-text-muted);
  margin: 0 0 var(--space-6);
}

/* Astra underlines links inside content areas. */
.siljora-empty a.siljora-hero-button,
.woocommerce .siljora-empty a.siljora-hero-button {
  text-decoration: none;
}

/* ==========================================================================
   Cookie consent
   ==========================================================================
   Anchored to the bottom rather than covering the page: the shop stays usable
   while the choice is pending, which is the point of asking rather than
   blocking. Both buttons are equally reachable — a decline that is harder to
   find than an accept is not consent. */
.siljora-consent {
  position: fixed;
  z-index: 9999;
  left: 50%;
  bottom: clamp(0.75rem, 2vw, 1.5rem);
  transform: translateX(-50%);
  width: min(calc(100% - 1.5rem), 46rem);
  background-color: var(--c-surface);
  color: var(--c-text);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
  box-shadow: 0 18px 48px rgba(31, 26, 22, 0.18);
  animation: siljora-consent-in 420ms var(--ease-out) both;
}

@keyframes siljora-consent-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .siljora-consent { animation: none; }
}

.siljora-consent__inner {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2rem);
  padding: clamp(1rem, 2.5vw, 1.5rem) clamp(1.1rem, 3vw, 1.75rem);
}

.siljora-consent__title {
  font-family: var(--font-display);
  font-size: 1.05rem;
  margin: 0 0 var(--space-2);
  color: var(--c-text);
}

.siljora-consent__text {
  font-size: 0.86rem;
  font-weight: 300;
  line-height: 1.6;
  color: var(--c-text-muted);
  margin: 0;
}

.siljora-consent__link {
  color: var(--c-accent-ink);
  text-decoration: underline;
  white-space: nowrap;
}

.siljora-consent__actions {
  display: flex;
  gap: var(--space-3);
  flex: none;
}

.siljora-consent__button {
  border-radius: var(--radius-btn);
  padding: 0.7em 1.5em;
  font-family: var(--font-body);
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out);
}

/* Astra recolours buttons on hover and focus, so every state restates its own
   colours — the same trap that once made a button's label vanish. */
.siljora-consent .siljora-consent__button--solid,
.siljora-consent .siljora-consent__button--solid:hover,
.siljora-consent .siljora-consent__button--solid:focus,
.siljora-consent .siljora-consent__button--solid:active {
  background-color: var(--c-text);
  border: 1px solid var(--c-text);
  color: var(--c-text-inverse);
}

.siljora-consent .siljora-consent__button--solid:hover,
.siljora-consent .siljora-consent__button--solid:focus {
  background-color: var(--c-accent-ink);
  border-color: var(--c-accent-ink);
}

.siljora-consent .siljora-consent__button--ghost,
.siljora-consent .siljora-consent__button--ghost:hover,
.siljora-consent .siljora-consent__button--ghost:focus,
.siljora-consent .siljora-consent__button--ghost:active {
  background-color: transparent;
  border: 1px solid var(--c-border-strong);
  color: var(--c-text);
}

.siljora-consent .siljora-consent__button--ghost:hover,
.siljora-consent .siljora-consent__button--ghost:focus {
  border-color: var(--c-text);
}

.siljora-consent__button:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 3px;
}

@media (max-width: 720px) {
  .siljora-consent__inner {
    flex-direction: column;
    align-items: stretch;
    text-align: left;
  }

  .siljora-consent__actions {
    justify-content: stretch;
  }

  .siljora-consent__button {
    flex: 1;
  }
}

/* ==========================================================================
   Coupon row in the totals
   ==========================================================================
   WooCommerce prints the discount and its remove link as one run of text, so
   "-$15.00 [Remove]" reads as a single value. The amount stays where it is,
   aligned with the other totals, and the remove control is pushed to the far
   end of the row where an action belongs. */
.woocommerce .cart_totals .cart-discount td,
.woocommerce table.shop_table .cart-discount td,
.woocommerce-checkout-review-order-table .cart-discount td {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

/* `auto` rather than space-between: the leading minus sign is its own text
   node, and space-between would strand it away from the figure. */
.woocommerce a.woocommerce-remove-coupon,
.woocommerce-page a.woocommerce-remove-coupon {
  margin-left: auto;
  flex: none;
  display: inline-flex;
  align-items: center;
  padding: 0.35em 0.9em;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-btn);
  font-family: var(--font-body);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out);
}

/* Astra recolours links on hover and focus, so each state restates its own
   colours — otherwise the label disappears into the fill. */
.woocommerce a.woocommerce-remove-coupon,
.woocommerce a.woocommerce-remove-coupon:link,
.woocommerce a.woocommerce-remove-coupon:visited {
  background-color: transparent;
  color: var(--c-text-muted);
}

.woocommerce a.woocommerce-remove-coupon:hover,
.woocommerce a.woocommerce-remove-coupon:focus {
  background-color: var(--c-text);
  border-color: var(--c-text);
  color: var(--c-text-inverse);
}

.woocommerce a.woocommerce-remove-coupon:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}

/* Stacked table layout on phones puts the row label in a ::before, so the
   amount and the button need to stay on one line beneath it. */
@media (max-width: 768px) {
  .woocommerce .cart_totals .cart-discount td,
  .woocommerce table.shop_table .cart-discount td,
  .woocommerce-checkout-review-order-table .cart-discount td {
    gap: var(--space-2) 0;
  }

  /* The stacked layout puts the row label in this pseudo-element, which would
     otherwise butt straight against the figure. Spaced with a margin rather
     than a column gap, because a gap would also push the leading minus sign
     away from the amount. */
  .woocommerce .cart_totals .cart-discount td::before,
  .woocommerce table.shop_table .cart-discount td::before,
  .woocommerce-checkout-review-order-table .cart-discount td::before {
    margin-right: var(--space-2);
  }
}

/* ==========================================================================
   Line-by-line text reveal
   ==========================================================================
   Paired with js/text-reveal.js, which wraps each rendered line in a mask.
   The lines carry the movement; the block they sit in only fades. */
.siljora-line {
  display: block;
  overflow: hidden;
  /* The mask would otherwise crop the descenders of this italic face, and the
     overhang of its slanted capitals. Padding opens the box; the matching
     negative margin keeps the layout exactly where it was. */
  padding: 0.1em 0.08em 0.16em;
  margin: -0.1em -0.08em -0.16em;
}

.siljora-line__inner {
  display: block;
  /* Must clear the mask's padding as well as the line itself, or the tops of
     the letters sit visible in that padded strip before the reveal runs. */
  transform: translateY(calc(100% + 0.4em));
  opacity: 0;
  transition: transform 0.9s var(--ease-out), opacity 0.7s var(--ease-out);
  /* Each line follows the one above it. */
  transition-delay: calc(var(--line, 0) * 85ms);
  will-change: transform;
}

.siljora-lines.is-revealed .siljora-line__inner {
  transform: translateY(0);
  opacity: 1;
}

/* Body copy carries more lines, so it moves less and follows more closely —
   a long paragraph rising as far as a headline reads as restless. */
.siljora-about-lede-text .siljora-line__inner,
.siljora-about-quote-text .siljora-line__inner {
  transform: translateY(calc(100% + 0.3em));
  transition-delay: calc(var(--line, 0) * 55ms);
}

/* When the lines animate, the surrounding block stops lifting and only fades,
   so the two movements do not fight each other. */
.siljora-reveal.siljora-reveal--lines {
  transform: none;
}

/* Copy that cannot be line-split — because it contains a link or emphasis —
   still animates, just as a single block. */
.siljora-text-fade {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}

.siljora-text-fade.is-revealed {
  opacity: 1;
  transform: none;
}

/* The script does not split anything when reduced motion is requested, but if
   a split has already happened the text must still be readable. */
@media (prefers-reduced-motion: reduce) {
  .siljora-line__inner,
  .siljora-text-fade {
    transform: none;
    opacity: 1;
    transition: none;
  }
}

/* ==========================================================================
   Sign in before checkout
   ==========================================================================
   Both controls take their metrics from one place. WooCommerce styles
   `a.checkout-button` on the cart far larger than an ordinary `.button`, so
   left alone the pair came out different sizes — the class is not used here
   for that reason. */
.siljora-checkout-lock {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.siljora-checkout-lock__note {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--c-text-muted);
}

.siljora-checkout-lock__actions {
  display: flex;
  gap: var(--space-3);
}

/* Stacked, not side by side: the totals column is around 320px wide, and two
   buttons sharing that space wrapped their labels onto two lines. */
.siljora-checkout-lock__actions {
  flex-direction: column;
}

/* One shared shape: same padding, type and border on both, so neither can
   drift if Astra or WooCommerce changes its own button metrics. */
.woocommerce .siljora-checkout-lock__actions > .button,
.woocommerce .siljora-checkout-lock__actions > a.button {
  width: 100%;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  margin: 0;
  padding: 1.05em 1.6em;
  border-radius: var(--radius-btn);
  border-width: 1px;
  border-style: solid;
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out);
}

/* Unavailable, but still a finished-looking control — a dashed outline reads
   as a placeholder rather than a disabled button. Astra recolours buttons on
   hover and focus, so each state restates its own colours. */
.woocommerce .siljora-checkout-lock__disabled,
.woocommerce .siljora-checkout-lock__disabled:hover,
.woocommerce .siljora-checkout-lock__disabled:focus,
.woocommerce .siljora-checkout-lock__disabled:active,
.woocommerce .siljora-checkout-lock__disabled[disabled] {
  background-color: var(--c-surface-muted);
  border-color: var(--c-border);
  color: var(--c-text-muted);
  cursor: not-allowed;
  opacity: 1;
  box-shadow: none;
}

/* WooCommerce ships a `:disabled[disabled]:hover` rule that paints disabled
   buttons in Astra's blue, and at (0,5,1) it outranks the block above — so
   hovering the greyed-out checkout button made it flash blue. `:hover` does
   match a disabled element, so this was visible, not theoretical. Matching
   the attribute and the pseudo-class takes this to (0,6,1). */
.woocommerce button.button.siljora-checkout-lock__disabled[disabled],
.woocommerce button.button.siljora-checkout-lock__disabled[disabled]:hover,
.woocommerce button.button.siljora-checkout-lock__disabled[disabled]:focus,
.woocommerce button.button.siljora-checkout-lock__disabled[disabled]:active,
.woocommerce button.button.siljora-checkout-lock__disabled:disabled:hover,
.woocommerce button.button.siljora-checkout-lock__disabled:disabled:focus {
  background-color: var(--c-surface-muted);
  border-color: var(--c-border);
  color: var(--c-text-muted);
}

.woocommerce a.siljora-checkout-lock__login,
.woocommerce a.siljora-checkout-lock__login:link,
.woocommerce a.siljora-checkout-lock__login:visited {
  background-color: var(--c-text);
  border-color: var(--c-text);
  color: var(--c-text-inverse);
}

.woocommerce a.siljora-checkout-lock__login:hover,
.woocommerce a.siljora-checkout-lock__login:focus {
  background-color: var(--c-accent-ink);
  border-color: var(--c-accent-ink);
  color: var(--c-text-inverse);
}

.woocommerce a.siljora-checkout-lock__login:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 3px;
}

.siljora-checkout-lock__alt {
  margin: 0;
  font-size: 0.82rem;
  color: var(--c-text-muted);
}

.siljora-checkout-lock__alt a {
  color: var(--c-accent-ink);
}


/* ==========================================================================
   Cart layout
   ==========================================================================
   WooCommerce stacks the basket above the totals and floats the totals to
   48% width, which leaves a large empty gap beside them. The two are put
   side by side instead — the form and `.cart-collaterals` are siblings inside
   `.woocommerce`, so that is the element doing the grid. */
.woocommerce-cart .woocommerce {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(20rem, 27%, 24rem);
  gap: clamp(1.5rem, 2.5vw, 2.5rem);
  align-items: start;
}

/* Notices and the empty-basket message belong across the full width, not
   squeezed into the first column. */
.woocommerce-cart .woocommerce > .woocommerce-notices-wrapper,
.woocommerce-cart .woocommerce > .cart-empty,
.woocommerce-cart .woocommerce > .wc-empty-cart-message,
.woocommerce-cart .woocommerce > .return-to-shop {
  grid-column: 1 / -1;
}

/* WooCommerce's own float and percentage width would fight the grid. */
.woocommerce-cart .cart-collaterals,
.woocommerce-cart .cart-collaterals .cart_totals {
  width: 100%;
  float: none;
  margin: 0;
}

.woocommerce-cart .woocommerce-cart-form {
  margin: 0;
}

/* A long basket can scroll past the totals; keeping them in view means the
   total and the checkout button stay reachable. */
@media (min-width: 901px) {
  .woocommerce-cart .cart-collaterals {
    position: sticky;
    top: var(--space-6);
  }
}

/* Below the breakpoint the totals return beneath the basket, where there is
   room to read them. */
@media (max-width: 900px) {
  .woocommerce-cart .woocommerce {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* -- Wishlist ------------------------------------------------------------ */
/* Saving a piece is a low-commitment act, so the control is quiet until it
   has been used. Filled means saved; outline means available. */
.siljora-wish {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  /* 44px floor: this is a one-handed, on-the-move tap on a phone, and the
     label alone leaves the box about ten pixels short of comfortable. */
  min-height: 44px;
  padding: 0.7em 1.4em;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-btn);
  background-color: transparent;
  box-shadow: none;
  color: var(--c-text);
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--t-base) var(--ease-out),
    background-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out);
}

/* Astra recolours buttons on hover AND focus, so every state restates its own
   colours. `:focus` has to be listed separately from `:focus-visible`: a mouse
   click sets :focus but not :focus-visible, so without it Astra's
   `button:focus { background: var(--ast-global-color-1) }` won and the control
   turned its default blue the moment it was clicked. */
.siljora-wish:hover,
.siljora-wish:focus,
.siljora-wish:focus-visible,
.siljora-wish:active,
.woocommerce .siljora-wish:hover,
.woocommerce .siljora-wish:focus,
.woocommerce .siljora-wish:focus-visible,
.woocommerce .siljora-wish:active {
  border-color: var(--c-text);
  background-color: transparent;
  color: var(--c-text);
}

.siljora-wish:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}

.siljora-wish__icon {
  display: inline-flex;
  align-items: center;
}

.siljora-wish__icon svg path {
  transition: fill var(--t-base) var(--ease-out),
    stroke var(--t-base) var(--ease-out);
}

.siljora-wish.is-saved .siljora-wish__icon svg path,
.siljora-wish:hover .siljora-wish__icon svg path {
  fill: var(--c-accent);
  stroke: var(--c-accent-ink);
}

.siljora-wish.is-saved,
.siljora-wish.is-saved:hover,
.siljora-wish.is-saved:focus,
.siljora-wish.is-saved:active,
.woocommerce .siljora-wish.is-saved,
.woocommerce .siljora-wish.is-saved:hover,
.woocommerce .siljora-wish.is-saved:focus,
.woocommerce .siljora-wish.is-saved:active {
  border-color: var(--c-accent-ink);
  color: var(--c-text);
}

/* currentColor drives the heart's stroke, so a stray `color: #fff` from the
   parent theme would erase the outline as well as the label. */
.siljora-wish.is-saved .siljora-wish__icon svg path,
.siljora-wish:focus .siljora-wish__icon svg path,
.siljora-wish:active .siljora-wish__icon svg path {
  stroke: var(--c-accent-ink);
}

.siljora-wish.is-saved .siljora-wish__icon svg path {
  fill: var(--c-accent);
}

/* An unsaved heart stays an outline, whatever the pointer is doing. */
.siljora-wish:not(.is-saved):focus .siljora-wish__icon svg path,
.siljora-wish:not(.is-saved):active .siljora-wish__icon svg path {
  fill: none;
}

.siljora-wish.is-pending {
  opacity: 0.6;
  pointer-events: none;
}

/* A single beat of acknowledgement — enough to notice, not enough to wait for. */
.siljora-wish.just-saved .siljora-wish__icon {
  animation: siljora-wish-pop 0.45s var(--ease-out);
}

@keyframes siljora-wish-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.28); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .siljora-wish.just-saved .siljora-wish__icon {
    animation: none;
  }
}

/* Icon-only, floated over the photograph on a catalogue card. */
.woocommerce ul.products li.product {
  position: relative;
}

/* Top-left, not top-right: Astra puts its own on-card cart button at
   top:16px right:16px and reveals it on hover, which landed it directly
   underneath this one. Separating them by position rather than by timing
   means neither can ever cover the other, in any state or on touch, where
   there is no hover to arbitrate between them. */
.siljora-wish--compact {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  right: auto;
  z-index: 6;
  gap: 0;
  width: 44px;
  height: 44px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border-color: transparent;
  border-radius: 999px;
  background-color: rgba(255, 255, 255, 0.9);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(2px);
}

.siljora-wish--compact:hover,
.siljora-wish--compact:focus,
.siljora-wish--compact:focus-visible,
.siljora-wish--compact:active,
.woocommerce .siljora-wish--compact:hover,
.woocommerce .siljora-wish--compact:focus,
.woocommerce .siljora-wish--compact:focus-visible,
.woocommerce .siljora-wish--compact:active {
  border-color: transparent;
  background-color: #ffffff;
  color: var(--c-text);
}

/* -- Wishlist page ------------------------------------------------------- */
/* The section is the page's only content, directly under Astra's page title,
   so the full homepage rhythm (var(--section-y) above and below, a 64px gap
   under the header) left 112px between the title and the eyebrow and another
   64px before the first card. Pulled in to read as one block. */
.siljora-section.siljora-wishlist {
  padding-top: var(--space-4);
  padding-bottom: var(--space-8);
}

.siljora-wishlist .siljora-section-header {
  margin-bottom: var(--space-6);
}

.siljora-wishlist__grid {
  align-items: start;
}

.siljora-wishlist__item {
  display: flex;
  flex-direction: column;
}

.siljora-wishlist__item .siljora-wish {
  align-self: start;
  margin-top: var(--space-3);
}

/* -- Saved count badge --------------------------------------------------- */
/* Lives in the profile dropdown now, not the nav bar, so the old
   .siljora-wish-item positioning and hover rules went with that move. */
.siljora-wish-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: var(--space-2);
  border-radius: 999px;
  background-color: var(--c-accent);
  color: var(--c-text);
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1;
  transition: background-color var(--t-base) var(--ease-out),
    transform var(--t-base) var(--ease-out);
}

/* Nothing saved shouldn't advertise a zero. */
.siljora-wish-count:not(.has-items) {
  display: none;
}


.siljora-wish-label {
  margin-left: 0.4em;
}

/* A piece leaving the wishlist fades rather than vanishing, so the grid does
   not jump under a thumb that is still resting on the screen. */
.siljora-wishlist__item {
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}

.siljora-wishlist__item.is-leaving {
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .siljora-wishlist__item {
    transition: none;
  }
}

/* WooCommerce's stock green is 2.54:1 on the cream surface — legible enough to
   a designer's eye, not to anyone with low vision. Darkened to pass AA while
   staying recognisably "in stock" green. */
.woocommerce .stock.in-stock,
.woocommerce div.product .stock.in-stock,
.woocommerce-page .stock.in-stock {
  color: #3d6b2a;
}

.woocommerce .stock.out-of-stock,
.woocommerce div.product .stock.out-of-stock {
  color: #8a2318;
}

/* Astra's category eyebrow on catalogue cards is #ae9b7b — 2.38:1 on the ivory
   ground, and set at 10px, which is the worst combination of small and faint.
   --c-accent-ink exists for gold that has to be read rather than admired. */
/* Unqualified on purpose: the eyebrow appears in more than one container
   (and outside the .woocommerce wrapper on the post-type archive), so
   scoping it to the shop grid leaves instances behind still failing. */
.ast-woo-product-category,
.woocommerce-loop-product__category {
  color: var(--c-accent-ink);
}

/* Astra ships its own rule at (0,4,2) — .woocommerce-page ul.products
   li.product .ast-woo-product-category — which the plain selector above
   cannot outrank. Adding the element qualifier takes it to (0,4,3) and
   settles it by specificity rather than by source order, which is the part
   a parent-theme update could quietly change.

   The opacity matters as much as the colour: Astra fades this text to .6,
   which blends even a passing colour back down — #7f6231 at 60% over the
   ivory ground is #ae9b7b, or 2.38:1. The muting is restored through the
   colour token instead, where it can be measured. */
.woocommerce-page ul.products li.product span.ast-woo-product-category,
.woocommerce ul.products li.product span.ast-woo-product-category,
.woocommerce-js ul.products li.product span.ast-woo-product-category,
.woocommerce-page ul.products li.product a.woocommerce-loop-product__category,
.woocommerce ul.products li.product a.woocommerce-loop-product__category {
  color: var(--c-accent-ink);
  opacity: 1;
}

/* ==========================================================================
   Astra's global palette, re-pointed at the brand
   ==========================================================================
   Astra ships a blue palette (--ast-global-color-0/1 are #046bd2 / #045cb4)
   and uses it for every control the child theme has not explicitly restyled:
   the mobile menu toggle, the search submit and close buttons, the carousel
   arrows and dots, Update cart, and the
   product gallery controls. Each of those was turning up in Astra blue on
   hover or focus, on a site otherwise set in warm ivory and champagne.

   Overriding the variables fixes all of them at once, and anything else
   Astra colours this way in future, instead of chasing one component at a
   time. This works because the child stylesheet is the last sheet in the
   head, so at equal (:root) specificity it wins on source order.

   Links are unaffected: they are already routed through the brand palette by
   the `a { color: var(--c-text) }` rule near the top of this file. */
:root {
  /* Primary action ground, and the hover/focus ground. Dark espresso resting,
     champagne on interaction — the same language as the site's own buttons.
     White text on #7f6231 is 5.69:1, so the hover state still passes AA. */
  --ast-global-color-0: #1f1a16;
  --ast-global-color-1: #7f6231;

  /* Headings and body copy. */
  --ast-global-color-2: #1f1a16;
  --ast-global-color-3: #645a52;

  /* Surfaces: white cards on the warm ivory ground, not Astra's cool #F0F5FA. */
  --ast-global-color-4: #ffffff;
  --ast-global-color-5: #f5f0e9;

  --ast-global-color-6: #1f1a16;
  --ast-global-color-7: rgba(31, 26, 22, 0.14);
  --ast-global-color-8: #1f1a16;

  --ast-border-color: rgba(31, 26, 22, 0.14);
}

/* WooCommerce's show/hide password eye is a 16x18 button pinned inside the
   field — below the 24px minimum, and it sits on the one form everybody has
   to use. Grown to a full 44px target, centred on the input.

   Centring uses ONE offset, stated explicitly. WooCommerce centres this
   button with the individual `translate` property (`translate: 0 -50%`), and
   `translate` and `transform` are independent properties that stack. An
   earlier version of this rule added `transform: translateY(-50%)` on top, so
   the button was lifted by half its height twice and sat 22px above the field.
   `transform: none` removes any second offset rather than relying on it being
   absent. */
.woocommerce .password-input .show-password-input,
.woocommerce-page .password-input .show-password-input,
.woocommerce form .password-input button.show-password-input {
  display: flex;
  align-items: center;
  justify-content: center;
  top: 50%;
  right: 2px;
  width: 44px;
  height: 44px;
  translate: 0 -50%;
  transform: none;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  line-height: 1;
}

/* The eye itself is WooCommerce's ::after icon-font glyph. As a flex child of
   the button it is centred by align-items/justify-content above; this only
   stops inherited line-height adding space beneath it and nudging it low. */
.woocommerce .password-input .show-password-input::after,
.woocommerce form .password-input button.show-password-input::after {
  display: block;
  line-height: 1;
}

.woocommerce .password-input .show-password-input:hover,
.woocommerce .password-input .show-password-input:focus,
.woocommerce .password-input .show-password-input:active,
.woocommerce form .password-input button.show-password-input:hover,
.woocommerce form .password-input button.show-password-input:focus,
.woocommerce form .password-input button.show-password-input:active {
  background: none;
  background-color: transparent;
  border-color: transparent;
  color: var(--c-text);
}

/* Links inside running text in the account and checkout forms — the privacy
   notice on sign-up, the terms line at checkout. The site-wide
   `a { text-decoration: none }` suits nav and card links, but here the link
   sits in a sentence and its colour differs from the text around it by only
   2.56:1, under the 3:1 needed for colour alone to mark it. Anyone who cannot
   see that difference could not tell it was a link at all (WCAG 1.4.1). An
   underline marks it regardless of colour.

   Astra removes underlines from every link inside WooCommerce page content
   with `.ast-single-post .entry-content .woocommerce a` at (0,3,1), which a
   plain class selector cannot beat. Each selector below carries that same
   prefix plus the form's own class, reaching (0,4,1) — so this wins on
   specificity rather than on source order. The unprefixed forms stay for
   templates without that body class. */
.ast-single-post .entry-content .woocommerce .woocommerce-privacy-policy-text a,
.ast-single-post .entry-content .woocommerce .woocommerce-terms-and-conditions-wrapper a,
.ast-single-post .entry-content .woocommerce .woocommerce-LostPassword a,
.woocommerce-privacy-policy-text a,
.woocommerce-terms-and-conditions-wrapper a,
.woocommerce-LostPassword a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.ast-single-post .entry-content .woocommerce .woocommerce-privacy-policy-text a:hover,
.ast-single-post .entry-content .woocommerce .woocommerce-terms-and-conditions-wrapper a:hover,
.ast-single-post .entry-content .woocommerce .woocommerce-LostPassword a:hover,
.woocommerce-privacy-policy-text a:hover,
.woocommerce-terms-and-conditions-wrapper a:hover,
.woocommerce-LostPassword a:hover {
  text-decoration-thickness: 2px;
}

/* ==========================================================================
   Compact vertical rhythm — Astra's own values
   ==========================================================================
   The rest of the tightening lives at the source rules (--section-y, the
   section heading gap, the header padding). These two values come from Astra
   itself, so they are overridden here. */

/* Astra gives the header row a fixed 80px minimum. With the bar's padding and
   the 36px logo, a 60px row still leaves the logo and links comfortable room,
   and every nav link inherits the row height, so tap targets stay generous. */
.site-header .ast-primary-header-bar .site-primary-header-wrap,
.site-header .ast-mobile-header-wrap .ast-primary-header-bar {
  min-height: 60px;
}

/* The min-height alone does not shrink the bar: Astra also sets
   `line-height: 80px` on every desktop menu item, and those items prop the row
   open by themselves. Astra's selector is
   `.ast-desktop:not(:has(.ast-header-sticked)) .ast-primary-header-bar
   .main-header-menu > .menu-item` at (0,5,0); this one is (0,6,0), so it wins
   on specificity rather than on source order. */
.ast-desktop .site-header .ast-primary-header-bar .ast-builder-menu-1 .main-header-menu > .menu-item {
  line-height: 60px;
}

/* The last thing holding the row open: Astra pads the logo block 16px above and
   below, making it 68px tall inside a 60px row. The row already centres it, so
   the padding only added height. */
.site-header .ast-primary-header-bar .site-branding.ast-site-identity {
  padding-top: 0;
  padding-bottom: 0;
}

@media (max-width: 921px) {
  .site-header .ast-primary-header-bar .site-primary-header-wrap,
  .site-header .ast-mobile-header-wrap .ast-primary-header-bar {
    min-height: 56px;
    padding-top: 0;
    padding-bottom: 0;
  }
}

/* Astra puts 60px above and below the content area on wide screens. */
@media (min-width: 922px) {
  body.ast-plain-container.ast-no-sidebar #primary {
    margin-top: var(--space-6);
    margin-bottom: var(--space-6);
  }
}

/* The homepage opens with the hero, whose own padding already spaces it from
   the header, so the content-area margin above it is only an extra band. */
@media (min-width: 922px) {
  body.home.ast-plain-container.ast-no-sidebar #primary {
    margin-top: 0;
    margin-bottom: 0;
  }
}

/* On phones Astra removes that margin entirely, which left page titles
   (Cart, My Account, Wishlist) sitting flush against the header line.

   The space goes on the title element, not on .entry-header: the homepage,
   About and Contact print an EMPTY zero-height .entry-header, and a margin on
   that wrapper pushed their content down 22px for no visible title. */
@media (max-width: 921px) {
  .ast-plain-container .entry-header .entry-title {
    margin-top: var(--space-5);
  }
}

/* ==========================================================================
   Checkout (see woocommerce/checkout/form-checkout.php, inc/checkout.php)
   ==========================================================================
   Contact → Delivery → Shipping method → Payment → Billing address down the
   left, order summary on the right. On narrow screens the summary moves to the
   top behind a "Show order summary" toggle. */

.woocommerce-checkout form.checkout.siljora-checkout {
  --co-field-h: 3.375rem;
  --co-radius: var(--radius-md);
  --co-border: rgba(31, 26, 22, 0.24);
  --co-selected: #fbf7f1;
  --co-error: #b3261e;

  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(18rem, 27rem);
  align-items: start;
  column-gap: clamp(var(--space-6), 5vw, var(--space-8));
  margin: 0;
}

/* WooCommerce prepends its error and update notices to the form itself, which
   would otherwise make them a grid cell squeezed beside the columns. */
.siljora-checkout > .woocommerce-NoticeGroup {
  grid-column: 1 / -1;
  grid-row: 1;
  margin-bottom: var(--space-5);
}

.siljora-checkout__main {
  grid-column: 1;
  grid-row: 2;
  min-width: 0;
}

.siljora-checkout__summary {
  grid-column: 2;
  grid-row: 2;
  position: sticky;
  top: var(--space-5);
  padding: var(--space-5);
  background: var(--c-surface-muted);
  border-radius: var(--radius-lg);
}

/* -- Sections -------------------------------------------------------------- */
.siljora-checkout__section {
  margin: 0 0 var(--space-6);
}

.siljora-checkout__section[hidden] {
  display: none;
}

.siljora-checkout__section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

.woocommerce-checkout .siljora-checkout .siljora-checkout__heading {
  margin: 0 0 var(--space-3);
  padding: 0;
  border: 0;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.375rem);
  font-weight: 600;
  line-height: var(--lh-heading);
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
}

.siljora-checkout__hint {
  margin: calc(-1 * var(--space-2)) 0 var(--space-3);
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
}

.ast-single-post .entry-content .woocommerce a.siljora-checkout__signin,
a.siljora-checkout__signin {
  font-size: var(--fs-sm);
  color: var(--c-text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* -- Fields: label inside the box ------------------------------------------
   Empty, a field shows its name as the placeholder. Once filled, the real
   label takes over, small, at the top of the box. Selects always hold a value,
   so theirs is always shown. */
.siljora-checkout .siljora-fields {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.woocommerce-checkout .siljora-checkout .siljora-fields .form-row {
  position: relative;
  flex: 1 1 100%;
  width: auto;
  float: none;
  margin: 0;
  padding: 0;
}

.woocommerce-checkout .siljora-checkout .siljora-fields .form-row-first,
.woocommerce-checkout .siljora-checkout .siljora-fields .form-row-last {
  flex-basis: calc(50% - var(--space-3) / 2);
}

/* City, county/state and postcode share a line and split whatever it holds. */
.woocommerce-checkout .siljora-checkout .siljora-fields .form-row[id$='_city_field'],
.woocommerce-checkout .siljora-checkout .siljora-fields .form-row[id$='_state_field'],
.woocommerce-checkout .siljora-checkout .siljora-fields .form-row[id$='_postcode_field'] {
  flex: 1 1 9rem;
}

.woocommerce-checkout .siljora-checkout .siljora-fields .form-row label {
  position: absolute;
  z-index: 1;
  top: 0.5rem;
  left: 0.875rem;
  right: 2.25rem;
  margin: 0;
  overflow: hidden;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--c-text-muted);
  pointer-events: none;
  transition: opacity var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out);
}

/* Required is the norm here; only "(optional)" is spelled out. */
.woocommerce-checkout .siljora-checkout .siljora-fields .form-row label .required {
  display: none;
}

.woocommerce-checkout .siljora-checkout .siljora-fields .form-row label .optional {
  color: inherit;
}

.woocommerce-checkout .siljora-checkout .siljora-fields input.input-text,
.woocommerce-checkout .siljora-checkout .siljora-fields select {
  display: block;
  width: 100%;
  height: var(--co-field-h);
  margin: 0;
  padding: 1.375rem 0.875rem 0.375rem;
  background-color: var(--c-surface);
  border: 1px solid var(--co-border);
  border-radius: var(--co-radius);
  box-shadow: none;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.4;
  color: var(--c-text);
  transition: border-color var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out),
    padding var(--t-base) var(--ease-out);
}

.woocommerce-checkout .siljora-checkout .siljora-fields select {
  padding-right: 2.5rem;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23645a52' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.95rem center;
  cursor: pointer;
}

.woocommerce-checkout .siljora-checkout .siljora-fields input.input-text::placeholder {
  color: var(--c-text-muted);
  opacity: 1;
}

.woocommerce-checkout .siljora-checkout .siljora-fields .form-row:has(input.input-text:placeholder-shown) label {
  opacity: 0;
  transform: translateY(0.25rem);
}

.woocommerce-checkout .siljora-checkout .siljora-fields input.input-text:placeholder-shown {
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
}

.woocommerce-checkout .siljora-checkout .siljora-fields input.input-text:focus,
.woocommerce-checkout .siljora-checkout .siljora-fields select:focus {
  outline: none;
  border-color: var(--c-text);
  box-shadow: 0 0 0 1px var(--c-text);
}

.woocommerce-checkout .siljora-checkout .siljora-fields .woocommerce-invalid input.input-text,
.woocommerce-checkout .siljora-checkout .siljora-fields .woocommerce-invalid select {
  border-color: var(--co-error);
}

.woocommerce-checkout .siljora-checkout .siljora-fields .woocommerce-invalid input.input-text:focus,
.woocommerce-checkout .siljora-checkout .siljora-fields .woocommerce-invalid select:focus {
  box-shadow: 0 0 0 1px var(--co-error);
}

.woocommerce-checkout .siljora-checkout .checkout-inline-error-message {
  margin: var(--space-1) 0 0;
  font-size: var(--fs-xs);
  color: var(--co-error);
}

/* -- Radio groups: payment, shipping method, billing address --------------- */
.woocommerce-checkout .siljora-checkout .siljora-choice-list,
.woocommerce-checkout #payment ul.payment_methods.siljora-choice-list {
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--c-surface);
  border: 1px solid var(--co-border);
  border-radius: var(--co-radius);
  overflow: hidden;
}

.woocommerce-checkout .siljora-checkout .siljora-choice,
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method {
  position: relative;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--co-border);
  list-style: none;
  transition: background-color var(--t-base) var(--ease-out);
}

.woocommerce-checkout .siljora-checkout .siljora-choice:first-child,
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method:first-child {
  border-top: 0;
}

/* Selected option: tinted and outlined, drawn inside so neighbours don't move. */
.woocommerce-checkout .siljora-checkout .siljora-choice:has(> .siljora-choice__row input:checked),
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method:has(> input:checked) {
  background: var(--co-selected);
  box-shadow: inset 0 0 0 1px var(--c-text);
}

.woocommerce-checkout .siljora-checkout .siljora-choice:first-child:has(> .siljora-choice__row input:checked),
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method:first-child:has(> input:checked) {
  border-radius: var(--co-radius) var(--co-radius) 0 0;
}

.woocommerce-checkout .siljora-checkout .siljora-choice:last-child:has(> .siljora-choice__row input:checked),
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method:last-child:has(> input:checked) {
  border-radius: 0 0 var(--co-radius) var(--co-radius);
}

.woocommerce-checkout .siljora-checkout .siljora-choice__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 3.5rem;
  margin: 0;
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
  cursor: pointer;
}

.siljora-checkout .siljora-choice__label {
  flex: 1 1 auto;
}

.siljora-checkout .siljora-choice__meta {
  flex: none;
  font-weight: 500;
}

/* WooCommerce's payment row is an input followed by a sibling label, not a
   label wrapping its input, so it is laid out as a grid instead. */
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: var(--space-3);
  padding: 0 var(--space-4);
}

.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method > label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 3.5rem;
  margin: 0;
  padding: var(--space-3) 0;
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.4;
  color: var(--c-text);
  cursor: pointer;
}

.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method > label img {
  max-height: 1.5rem;
  margin: 0 0 0 auto;
}

.woocommerce-checkout .siljora-checkout .siljora-choice__row input[type='radio'],
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method > input[type='radio'] {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin: 0;
  accent-color: var(--c-text);
  cursor: pointer;
}

/* WooCommerce clears floats in each row with ::before/::after, and in a grid
   those pseudo-elements take the first cells and push the radio off its label.
   Each child is also placed explicitly. */
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method::before,
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method::after {
  content: none;
}

.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method > input[type='radio'] {
  grid-column: 1;
  grid-row: 1;
}

.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method > label {
  grid-column: 2;
  grid-row: 1;
}

/* The description under a payment option: a plain continuation of the row,
   not WooCommerce's grey speech bubble. */
.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method .payment_box {
  grid-column: 1 / -1;
  grid-row: 2;
  margin: 0;
  padding: 0 0 var(--space-4) calc(1.125rem + var(--space-3));
  background: transparent;
  border-radius: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-text-muted);
}

.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method .payment_box::before {
  content: none;
}

.woocommerce-checkout #payment ul.payment_methods li.wc_payment_method .payment_box p {
  margin: 0;
}

.woocommerce-checkout .siljora-checkout #payment {
  background: transparent;
  border-radius: 0;
}

.woocommerce-checkout .siljora-checkout .siljora-choice__panel {
  padding: 0 var(--space-4) var(--space-4);
}

.woocommerce-checkout .siljora-checkout .siljora-choice__panel[hidden] {
  display: none;
}

/* -- Place order ----------------------------------------------------------- */
.woocommerce-checkout .siljora-checkout .siljora-place-order {
  float: none;
  width: auto;
  margin: 0;
  padding: 0;
}

.woocommerce-checkout .siljora-checkout .woocommerce-terms-and-conditions-wrapper {
  margin-bottom: var(--space-4);
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
}

/* The site-wide form label style is small spaced capitals, meant for field
   names; the terms checkbox is a sentence. */
.woocommerce-checkout .siljora-checkout .woocommerce-terms-and-conditions-wrapper .form-row label.woocommerce-form__label-for-checkbox {
  position: relative;
  display: block;
  margin: 0;
  padding-left: calc(1.125rem + var(--space-2));
  font-size: var(--fs-sm);
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.5;
  color: var(--c-text);
  cursor: pointer;
}

.woocommerce-checkout .siljora-checkout .woocommerce-terms-and-conditions-wrapper input[type='checkbox'] {
  position: absolute;
  top: 0.19rem;
  left: 0;
  width: 1.125rem;
  height: 1.125rem;
  margin: 0;
  accent-color: var(--c-text);
}

.woocommerce-checkout .siljora-checkout .woocommerce-terms-and-conditions-wrapper .form-row {
  margin: 0;
  padding: 0;
}

.woocommerce-checkout .siljora-checkout .woocommerce-privacy-policy-text p {
  margin: 0 0 var(--space-3);
}

.woocommerce-checkout .siljora-checkout #place_order.siljora-place-order__button {
  display: flex;
  align-items: center;
  justify-content: center;
  float: none;
  width: 100%;
  min-height: 3.5rem;
  margin: 0;
  font-size: var(--fs-body);
}

.siljora-checkout__policies {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--c-border-light);
}

.siljora-checkout__policies ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ast-single-post .entry-content .woocommerce .siljora-checkout__policies a,
.siljora-checkout__policies a {
  display: inline-block;
  padding: var(--space-2) 0;
  font-size: var(--fs-xs);
  color: var(--c-text-muted);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.ast-single-post .entry-content .woocommerce .siljora-checkout__policies a:hover,
.siljora-checkout__policies a:hover {
  color: var(--c-text);
}

/* -- Order summary --------------------------------------------------------- */
/* Astra floats the review to 40% width, and pads and borders it with
   `form #order_review:not(.elementor-widget-… #order_review)` — the :not()
   brings a second ID, (2,1,1). Repeating the ID matches that; the classes win. */
.woocommerce-checkout .woocommerce form.checkout.siljora-checkout #order_review#order_review {
  float: none;
  width: auto;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
}

.siljora-summary-items {
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
}

.siljora-summary-item {
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-4);
  margin: 0;
}

.siljora-summary-item + .siljora-summary-item {
  margin-top: var(--space-4);
}

.siljora-summary-item__media {
  position: relative;
  display: block;
  width: 4rem;
  height: 4rem;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
}

.siljora-summary-item__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: calc(var(--radius-md) - 1px);
}

.siljora-summary-item__qty {
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  display: grid;
  place-items: center;
  min-width: 1.375rem;
  height: 1.375rem;
  padding: 0 0.375rem;
  border-radius: var(--radius-pill);
  background: var(--c-text);
  box-shadow: 0 0 0 2px var(--c-surface-muted);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1;
  color: var(--c-text-inverse);
}

.siljora-summary-item__info {
  min-width: 0;
  font-size: var(--fs-sm);
  line-height: 1.4;
}

.siljora-summary-item__name {
  display: block;
  font-weight: 500;
  color: var(--c-text);
}

.siljora-summary-item__info dl.variation {
  margin: var(--space-1) 0 0;
  font-size: var(--fs-xs);
  color: var(--c-text-muted);
}

.siljora-summary-item__info dl.variation dt,
.siljora-summary-item__info dl.variation dd,
.siljora-summary-item__info dl.variation p {
  display: inline;
  margin: 0;
  padding: 0;
}

.siljora-summary-item__price {
  font-size: var(--fs-sm);
  font-weight: 500;
  white-space: nowrap;
}

/* Discount code */
.siljora-coupon {
  margin: 0 0 var(--space-5);
}

.siljora-coupon__row {
  display: flex;
  gap: var(--space-2);
}

.woocommerce-checkout .siljora-checkout input.siljora-coupon__input {
  flex: 1 1 auto;
  min-width: 0;
  height: 3rem;
  margin: 0;
  padding: 0 0.875rem;
  background: var(--c-surface);
  border: 1px solid var(--co-border);
  border-radius: var(--co-radius);
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--c-text);
}

.woocommerce-checkout .siljora-checkout input.siljora-coupon__input::placeholder {
  color: var(--c-text-muted);
  opacity: 1;
}

.woocommerce-checkout .siljora-checkout input.siljora-coupon__input:focus {
  outline: none;
  border-color: var(--c-text);
  box-shadow: 0 0 0 1px var(--c-text);
}

.woocommerce-checkout .siljora-checkout input.siljora-coupon__input[aria-invalid='true'] {
  border-color: var(--co-error);
}

.woocommerce-checkout .siljora-checkout button.siljora-coupon__apply,
.woocommerce-checkout .siljora-checkout button.siljora-coupon__apply:hover,
.woocommerce-checkout .siljora-checkout button.siljora-coupon__apply:focus {
  flex: none;
  height: 3rem;
  margin: 0;
  padding: 0 var(--space-5);
  background: var(--c-text);
  border: 1px solid var(--c-text);
  border-radius: var(--co-radius);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text-inverse);
  cursor: pointer;
}

.woocommerce-checkout .siljora-checkout button.siljora-coupon__apply:hover {
  background: var(--c-dark);
}

.woocommerce-checkout .siljora-checkout button.siljora-coupon__apply:focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 2px;
}

.woocommerce-checkout .siljora-checkout button.siljora-coupon__apply:disabled {
  opacity: 0.6;
  cursor: progress;
}

.siljora-coupon__message {
  margin: var(--space-2) 0 0;
  font-size: var(--fs-xs);
  color: var(--c-text-muted);
}

.siljora-coupon__message:empty {
  display: none;
}

.siljora-coupon__message.is-error {
  color: var(--co-error);
}

/* Totals */
.woocommerce-checkout .siljora-checkout table.siljora-summary-totals {
  width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.woocommerce-checkout .siljora-checkout table.siljora-summary-totals th,
.woocommerce-checkout .siljora-checkout table.siljora-summary-totals td {
  padding: var(--space-1) 0;
  border: 0;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
  vertical-align: baseline;
}

.woocommerce-checkout .siljora-checkout table.siljora-summary-totals th {
  text-align: left;
}

.woocommerce-checkout .siljora-checkout table.siljora-summary-totals td {
  text-align: right;
}

.woocommerce-checkout .siljora-checkout table.siljora-summary-totals tr.order-total th,
.woocommerce-checkout .siljora-checkout table.siljora-summary-totals tr.order-total td {
  padding-top: var(--space-4);
  font-size: 1.25rem;
  font-weight: 600;
}

.woocommerce-checkout .siljora-checkout table.siljora-summary-totals tr.order-total td strong {
  font-weight: 600;
}

.siljora-summary-muted {
  color: var(--c-text-muted);
}

/* Coupon rows: the amount then its remove control, kept on one line. */
.woocommerce-checkout .siljora-checkout table.siljora-summary-totals .cart-discount td {
  display: table-cell;
}

.woocommerce-checkout .siljora-checkout table.siljora-summary-totals .cart-discount td a.woocommerce-remove-coupon {
  margin-left: var(--space-2);
  vertical-align: middle;
}

/* -- Summary toggle (narrow screens) --------------------------------------- */
.siljora-summary-toggle[hidden] {
  display: none;
}

@media (max-width: 921px) {
  .woocommerce-checkout form.checkout.siljora-checkout {
    grid-template-columns: minmax(0, 1fr);
  }

  .siljora-checkout__summary {
    grid-column: 1;
    grid-row: 2;
    position: static;
    margin-bottom: var(--space-6);
    padding: 0;
    border-radius: var(--radius-md);
  }

  .siljora-checkout__main {
    grid-row: 3;
  }

  .woocommerce-checkout .woocommerce form.checkout.siljora-checkout #order_review#order_review {
    padding: 0 var(--space-4) var(--space-4);
  }

  .siljora-checkout__summary.is-collapsible:not(.is-open) #order_review {
    display: none;
  }

  .woocommerce-checkout .siljora-checkout button.siljora-summary-toggle,
  .woocommerce-checkout .siljora-checkout button.siljora-summary-toggle:hover,
  .woocommerce-checkout .siljora-checkout button.siljora-summary-toggle:focus {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 3.5rem;
    margin: 0;
    padding: var(--space-3) var(--space-4);
    background: transparent;
    border: 0;
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    text-align: left;
    color: var(--c-text);
    cursor: pointer;
  }

  .woocommerce-checkout .siljora-checkout button.siljora-summary-toggle:focus-visible {
    outline: 2px solid var(--c-text);
    outline-offset: -2px;
  }

  .siljora-summary-toggle__label {
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  .siljora-summary-toggle__chevron {
    transition: transform var(--t-base) var(--ease-out);
  }

  .siljora-summary-toggle[aria-expanded='true'] .siljora-summary-toggle__chevron {
    transform: rotate(180deg);
  }

  .siljora-summary-toggle__total {
    margin-left: auto;
    font-size: var(--fs-body);
    font-weight: 600;
  }
}

@media (prefers-reduced-motion: reduce) {
  .woocommerce-checkout .siljora-checkout .siljora-fields .form-row label,
  .woocommerce-checkout .siljora-checkout .siljora-fields input.input-text,
  .siljora-summary-toggle__chevron {
    transition: none;
  }
}

/* ==========================================================================
   Cart: basket and totals as soft panels, like the checkout summary
   ==========================================================================
   The basket is still WooCommerce's table — its scripts find the remove links,
   quantity inputs and coupon form by that markup — but each row is laid out as
   a grid: photograph, name with unit price, quantity, line total, remove.

   Many selectors carry `#content`: WooCommerce and Astra size the coupon field
   and button with ID-based rules (`#content table.cart td.actions …`) that no
   class selector can outrank. */

.woocommerce-cart .woocommerce-cart-form,
.woocommerce-cart .cart-collaterals .cart_totals {
  --cart-border: rgba(31, 26, 22, 0.24);

  box-sizing: border-box;
  padding: var(--space-5);
  background: var(--c-surface-muted);
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: none;
}

/* -- Basket ----------------------------------------------------------------- */
body.woocommerce-cart #content table.shop_table.cart {
  display: block;
  width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* Column headings are replaced by the layout itself; each control keeps its
   own accessible name (remove link and quantity field are labelled). */
body.woocommerce-cart #content table.shop_table.cart thead {
  display: none;
}

body.woocommerce-cart #content table.shop_table.cart tbody {
  display: block;
}

body.woocommerce-cart #content table.shop_table.cart tr.cart_item {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto minmax(5.5rem, auto) 2.25rem;
  grid-template-areas:
    'thumb name  qty subtotal remove'
    'thumb price qty subtotal remove';
  align-items: center;
  column-gap: var(--space-4);
  row-gap: var(--space-1);
  margin: 0;
  padding: var(--space-4) 0;
  border-top: 1px solid var(--c-border);
  background: transparent;
}

body.woocommerce-cart #content table.shop_table.cart tr.cart_item:first-child {
  padding-top: 0;
  border-top: 0;
}

/* Astra gives every cart cell `min-height: 3.25em`, which stretched each
   grid row and opened a gap between a name and its price. WooCommerce's
   phone stylesheet right-aligns every cell with !important, so alignment has
   to answer in kind. */
body.woocommerce-cart #content table.shop_table.cart tr.cart_item td {
  display: block;
  width: auto;
  min-width: 0;
  min-height: 0;
  text-align: left !important;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  font-size: var(--fs-sm);
  line-height: 1.4;
}

/* WooCommerce's phone layout labels every cell ("Price:", "Quantity:"). */
body.woocommerce-cart #content table.shop_table.cart tr.cart_item td::before {
  content: none;
  display: none;
}

body.woocommerce-cart #content table.shop_table.cart td.product-thumbnail {
  grid-area: thumb;
  align-self: center;
}

body.woocommerce-cart #content table.shop_table.cart td.product-thumbnail a {
  display: block;
}

body.woocommerce-cart #content table.shop_table.cart td.product-thumbnail img {
  display: block;
  box-sizing: border-box;
  width: 4.5rem;
  height: 4.5rem;
  max-width: none;
  object-fit: cover;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-md);
}

body.woocommerce-cart #content table.shop_table.cart td.product-name {
  grid-area: name;
  align-self: end;
  font-size: var(--fs-body);
  font-weight: 500;
}

.ast-single-post .entry-content .woocommerce-cart-form td.product-name a,
body.woocommerce-cart #content table.shop_table.cart td.product-name a {
  color: var(--c-text);
  text-decoration: none;
}

body.woocommerce-cart #content table.shop_table.cart td.product-name a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

body.woocommerce-cart #content table.shop_table.cart td.product-name dl.variation {
  margin: var(--space-1) 0 0;
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--c-text-muted);
}

body.woocommerce-cart #content table.shop_table.cart td.product-price {
  grid-area: price;
  align-self: start;
  font-size: var(--fs-xs);
  color: var(--c-text-muted);
}

body.woocommerce-cart #content table.shop_table.cart td.product-quantity {
  grid-area: qty;
}

body.woocommerce-cart #content table.shop_table.cart td.product-quantity .quantity {
  float: none;
  margin: 0;
}

body.woocommerce-cart #content table.shop_table.cart td.product-quantity input.qty {
  box-sizing: border-box;
  width: 4.25rem;
  height: 2.75rem;
  margin: 0;
  padding: 0 0.5rem;
  background: var(--c-surface);
  border: 1px solid var(--cart-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: 1rem;
  text-align: center;
  color: var(--c-text);
}

body.woocommerce-cart #content table.shop_table.cart td.product-quantity input.qty:focus {
  outline: none;
  border-color: var(--c-text);
  box-shadow: 0 0 0 1px var(--c-text);
}

body.woocommerce-cart #content table.shop_table.cart td.product-subtotal {
  grid-area: subtotal;
  text-align: right !important;
  font-size: var(--fs-body);
  font-weight: 500;
  white-space: nowrap;
  color: var(--c-text);
}

body.woocommerce-cart #content table.shop_table.cart td.product-remove {
  grid-area: remove;
  justify-self: end;
  align-self: center;
}

body.woocommerce-cart #content table.shop_table.cart td.product-remove a.remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--c-text-muted) !important; /* WooCommerce colours it red with !important. */
  transition: background-color var(--t-base) var(--ease-out), color var(--t-base) var(--ease-out);
}

body.woocommerce-cart #content table.shop_table.cart td.product-remove a.remove:hover,
body.woocommerce-cart #content table.shop_table.cart td.product-remove a.remove:focus-visible {
  background: var(--c-surface);
  color: var(--c-text) !important;
}

body.woocommerce-cart #content table.shop_table.cart td.product-remove a.remove:focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 1px;
}

body.woocommerce-cart #content table.shop_table.cart td.product-remove a.remove svg {
  width: 1.125rem;
  height: 1.125rem;
}

/* -- Discount code row ------------------------------------------------------ */
body.woocommerce-cart #content table.shop_table.cart tr:not(.cart_item) {
  display: block;
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--c-border);
}

body.woocommerce-cart #content table.shop_table.cart td.actions {
  display: block;
  padding: 0;
  border: 0;
  background: transparent;
  text-align: left;
}

body.woocommerce-cart #content table.shop_table.cart td.actions::before {
  content: none;
  display: none;
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon {
  display: flex;
  align-items: stretch;
  gap: var(--space-2);
  float: none;
  width: 100%;
  max-width: 30rem;
  margin: 0;
  padding: 0;
  border: 0;
}

/* A clearfix ::before/::after on the row became an empty flex item, and the
   gap after it pushed the field in from the panel edge. */
body.woocommerce-cart #content table.shop_table.cart td.actions .coupon::before,
body.woocommerce-cart #content table.shop_table.cart td.actions .coupon::after {
  content: none;
  display: none;
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon #coupon_code {
  box-sizing: border-box;
  flex: 1 1 auto;
  float: none;
  width: auto;
  min-width: 0;
  max-width: none;
  height: 3rem;
  margin: 0;
  padding: 0 0.875rem;
  background: var(--c-surface);
  border: 1px solid var(--cart-border);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--c-text);
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon #coupon_code::placeholder {
  color: var(--c-text-muted);
  opacity: 1;
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon #coupon_code:focus {
  outline: none;
  border-color: var(--c-text);
  box-shadow: 0 0 0 1px var(--c-text);
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon button.button,
body.woocommerce-cart #content table.shop_table.cart td.actions .coupon button.button:hover,
body.woocommerce-cart #content table.shop_table.cart td.actions .coupon button.button:focus {
  box-sizing: border-box;
  flex: 0 0 auto;
  float: none;
  width: auto;
  height: 3rem;
  margin: 0;
  padding: 0 var(--space-5);
  overflow: visible;
  background: var(--c-text);
  border: 1px solid var(--c-text);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  color: var(--c-text-inverse);
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon button.button:hover {
  background: var(--c-dark);
}

body.woocommerce-cart #content table.shop_table.cart td.actions .coupon button.button:focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 2px;
}

/* -- Totals ----------------------------------------------------------------- */
body.woocommerce-cart #content .cart-collaterals .cart_totals > h2 {
  margin: 0 0 var(--space-4);
  padding: 0;
  border: 0;
  background: transparent;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.375rem);
  font-weight: 600;
  line-height: var(--lh-heading);
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table {
  display: table;
  width: 100%;
  margin: 0 0 var(--space-5);
  border: 0;
  border-radius: 0;
  background: transparent;
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table tr {
  display: table-row;
  background: transparent;
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table th,
body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table td {
  display: table-cell;
  width: auto;
  padding: var(--space-1) 0;
  border: 0;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  vertical-align: baseline;
  color: var(--c-text);
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table th {
  text-align: left;
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table td {
  text-align: right;
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table td::before {
  content: none;
  display: none;
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table tr.order-total th,
body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table tr.order-total td {
  padding-top: var(--space-4);
  font-size: 1.25rem;
  font-weight: 600;
}

body.woocommerce-cart #content .cart-collaterals .cart_totals table.shop_table tr.order-total td strong {
  font-weight: 600;
}

body.woocommerce-cart #content .cart-collaterals .wc-proceed-to-checkout {
  margin: 0;
  padding: 0;
}

/* Signed in: WooCommerce's own button. Signed out: the sign-in pair from
   inc/require-login.php. Both take the checkout panel's rounded shape. */
body.woocommerce-cart #content .cart-collaterals .wc-proceed-to-checkout a.checkout-button {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 100%;
  min-height: 3.25rem;
  margin: 0;
  padding: 0 var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
}

body.woocommerce-cart #content .cart-collaterals .siljora-checkout-lock__actions > .button,
body.woocommerce-cart #content .cart-collaterals .siljora-checkout-lock__actions > a.button {
  min-height: 3.25rem;
  border-radius: var(--radius-md);
}

/* -- Phones ----------------------------------------------------------------- */
@media (max-width: 600px) {
  .woocommerce-cart .woocommerce-cart-form,
  .woocommerce-cart .cart-collaterals .cart_totals {
    padding: var(--space-4);
    border-radius: var(--radius-md);
  }

  body.woocommerce-cart #content table.shop_table.cart tr.cart_item {
    grid-template-columns: 4.5rem minmax(0, 1fr) auto;
    grid-template-areas:
      'thumb name  remove'
      'thumb price price'
      'thumb qty   subtotal';
    align-items: start;
    column-gap: var(--space-3);
    row-gap: var(--space-2);
  }

  body.woocommerce-cart #content table.shop_table.cart td.product-name {
    align-self: center;
  }

  body.woocommerce-cart #content table.shop_table.cart td.product-subtotal {
    align-self: center;
  }

  body.woocommerce-cart #content table.shop_table.cart td.actions .coupon {
    max-width: none;
  }
}

/* ==========================================================================
   Store location (see siljora_store_page_shortcode)
   ========================================================================== */
.siljora-store__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--space-5), 4vw, var(--space-7));
  align-items: start;
}

.siljora-store__grid--solo {
  grid-template-columns: minmax(0, 40rem);
  justify-content: center;
}

.siljora-store__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: clamp(var(--space-5), 3vw, var(--space-6));
  background: var(--c-surface-muted);
  border-radius: var(--radius-lg);
}

.siljora-store__block {
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--c-border);
}

.siljora-store__block:last-of-type {
  padding-bottom: 0;
  border-bottom: 0;
}

.siljora-store .siljora-store__heading {
  margin: 0 0 var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent-ink);
}

.siljora-store__address,
.siljora-store__text {
  margin: 0;
  font-size: var(--fs-body-lg);
  font-style: normal;
  line-height: var(--lh-body);
  color: var(--c-text);
}

.siljora-store .siljora-store__hours,
.siljora-store .siljora-store__contact {
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-body);
  line-height: 1.8;
  color: var(--c-text);
}

.ast-single-post .entry-content .siljora-store a.siljora-store__link,
.ast-single-post .entry-content .siljora-store__contact a,
.siljora-store a.siljora-store__link,
.siljora-store__contact a {
  color: var(--c-text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.siljora-store a.siljora-store__link {
  display: inline-block;
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
}

.siljora-store__button {
  align-self: flex-start;
}

.siljora-store__media {
  margin: 0;
  aspect-ratio: 1 / 1;
  max-width: 100%;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--c-surface-muted);
}

.siljora-store__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.siljora-store__visit {
  margin-top: clamp(var(--space-7), 6vw, var(--space-8));
}

.siljora-store .siljora-store__visit-title {
  margin: 0 0 var(--space-6);
  text-align: center;
}

@media (max-width: 800px) {
  .siljora-store__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .siljora-store__media {
    aspect-ratio: 4 / 3;
  }

  .siljora-store__button {
    align-self: stretch;
    text-align: center;
    justify-content: center;
  }
}

/* ==========================================================================
   Blogs & News (see siljora_blog_page_shortcode)
   ========================================================================== */
.siljora-blog__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--space-5), 3vw, var(--space-6));
}

.siljora-blog__card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--c-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--t-base) var(--ease-out), transform var(--t-base) var(--ease-out);
}

.siljora-blog__card:hover {
  box-shadow: var(--shadow-md);
}

.siljora-blog__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--c-surface-muted);
}

.siljora-blog__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms var(--ease-out);
}

.siljora-blog__card:hover .siljora-blog__media img {
  transform: scale(1.03);
}

.siljora-blog__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-5);
}

.siljora-blog__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--fs-label);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-accent-ink);
}

.siljora-blog .siljora-blog__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 1.6vw, 1.35rem);
  font-weight: 500;
  line-height: var(--lh-heading);
}

.ast-single-post .entry-content .siljora-blog__title a,
.siljora-blog__title a {
  color: var(--c-text);
  text-decoration: none;
}

/* The whole card is the target for pointer users: the title link stretches
   over it, while the image link is hidden from keyboards and screen readers so
   each article is one stop, not three. */
.siljora-blog__card {
  position: relative;
}

.siljora-blog__title a::after {
  content: '';
  position: absolute;
  inset: 0;
}

.siljora-blog__title a:focus-visible {
  outline: none;
}

.siljora-blog__card:has(.siljora-blog__title a:focus-visible) {
  outline: 2px solid var(--c-text);
  outline-offset: 3px;
}

.siljora-blog__excerpt {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-text-muted);
}

.ast-single-post .entry-content a.siljora-blog__more,
a.siljora-blog__more {
  position: relative;
  z-index: 1;
  align-self: flex-start;
  margin-top: auto;
  padding-top: var(--space-3);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--c-text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.siljora-blog__empty {
  text-align: center;
  color: var(--c-text-muted);
}

.siljora-blog__pages {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-7);
}

.siljora-blog__pages .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  height: 2.75rem;
  padding: 0 var(--space-3);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius-pill);
  color: var(--c-text);
  text-decoration: none;
}

.siljora-blog__pages .page-numbers.current {
  background: var(--c-text);
  border-color: var(--c-text);
  color: var(--c-text-inverse);
}

@media (max-width: 921px) {
  .siljora-blog__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 600px) {
  .siljora-blog__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (prefers-reduced-motion: reduce) {
  .siljora-blog__card,
  .siljora-blog__media img {
    transition: none;
  }

  .siljora-blog__card:hover .siljora-blog__media img {
    transform: none;
  }
}

/* A post's Featured image, placed under its title (siljora_post_featured_image). */
.siljora-post-hero {
  margin: 0 0 var(--space-6);
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--c-surface-muted);
}

.siljora-post-hero img {
  display: block;
  width: 100%;
  max-height: 32rem;
  object-fit: cover;
}

/* Phones, two products per row: the card heart scales with the smaller
   photograph. 38px stays a comfortable touch target. Placed after the
   base .siljora-wish--compact rule so it wins on source order. */
@media (max-width: 600px) {
  .woocommerce ul.products li.product .siljora-wish--compact {
    top: var(--space-2);
    left: var(--space-2);
    width: 38px;
    height: 38px;
  }
}

/* ==========================================================================
   Sign in / create account (woocommerce/myaccount/form-login.php)
   ==========================================================================
   One card, in the same warm-panel language as the basket and checkout: the
   form on a white panel, a photograph and the reasons to have an account
   beside it. Both of WooCommerce's forms are in the page; the body class set
   by siljora_account_body_class() decides which one is shown. */

.woocommerce-account .siljora-auth {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: stretch;
  max-width: 62rem;
  margin: 0 auto;
  overflow: hidden;
  background: var(--c-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.woocommerce-account .siljora-auth--single {
  grid-template-columns: minmax(0, 1fr);
  max-width: 34rem;
}

.woocommerce-account .siljora-auth__panel {
  padding: clamp(var(--space-5), 3vw, var(--space-6));
}

/* -- Tabs ------------------------------------------------------------------ */
.siljora-auth__tabs {
  display: flex;
  gap: var(--space-1);
  margin: 0 0 var(--space-5);
  padding: 4px;
  background: var(--c-surface-muted);
  border-radius: var(--radius-pill);
}

.ast-single-post .entry-content .woocommerce a.siljora-auth__tab,
.woocommerce-account a.siljora-auth__tab {
  flex: 1 1 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: 0 var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-align: center;
  text-decoration: none;
  color: var(--c-text-muted);
  transition: background-color var(--t-base) var(--ease-out), color var(--t-base) var(--ease-out);
}

.woocommerce-account a.siljora-auth__tab:hover {
  color: var(--c-text);
}

/* Astra colours links inside WooCommerce content at (0,3,1); the prefixed
   form below matches it and wins on order, so the selected tab's label is
   ivory on espresso rather than muted brown on espresso (2.5:1). */
.ast-single-post .entry-content .woocommerce a.siljora-auth__tab[aria-current='page'],
.woocommerce-account a.siljora-auth__tab[aria-current='page'] {
  background: var(--c-text);
  color: var(--c-text-inverse);
  box-shadow: var(--shadow-sm);
}

.woocommerce-account a.siljora-auth__tab:focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 2px;
}

/* -- Headings and fields --------------------------------------------------- */
.woocommerce-account .siljora-auth__title {
  margin: 0 0 var(--space-2);
  padding: 0;
  border: 0;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.4vw, 1.7rem);
  font-weight: 500;
  line-height: var(--lh-heading);
  color: var(--c-text);
}

.woocommerce-account .siljora-auth .siljora-auth__lede,
.siljora-auth__lede {
  margin: 0 0 var(--space-5);
  font-size: var(--fs-sm);
  line-height: var(--lh-body);
  color: var(--c-text-muted);
}

.woocommerce-account .siljora-auth .form-row {
  margin: 0 0 var(--space-4);
  padding: 0;
}

/* Field names read as words here, not as the letterspaced micro-labels used
   in the catalogue filters. */
.woocommerce-account .siljora-auth form .form-row label {
  margin-bottom: var(--space-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
}

.woocommerce-account .siljora-auth form .form-row label .required {
  color: var(--c-accent-ink);
}

.woocommerce-account .siljora-auth input[type='text'],
.woocommerce-account .siljora-auth input[type='email'],
.woocommerce-account .siljora-auth input[type='password'],
.woocommerce-account .siljora-auth input[type='tel'],
.woocommerce-account .siljora-auth form .form-row input.input-text {
  box-sizing: border-box;
  width: 100%;
  height: 3.125rem;
  padding: 0 0.95rem;
  background: var(--c-surface);
  border: 1px solid rgba(31, 26, 22, 0.24);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--c-text);
  transition: border-color var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out);
}

.woocommerce-account .siljora-auth input[type='text']:focus,
.woocommerce-account .siljora-auth input[type='email']:focus,
.woocommerce-account .siljora-auth input[type='password']:focus,
.woocommerce-account .siljora-auth input[type='tel']:focus,
.woocommerce-account .siljora-auth form .form-row input.input-text:focus {
  outline: none;
  border-color: var(--c-text);
  box-shadow: 0 0 0 1px var(--c-text);
}

/* The show/hide eye sits inside the taller field. */
.woocommerce-account .siljora-auth .password-input {
  display: block;
  position: relative;
}

.woocommerce-account .siljora-auth .password-input input.input-text {
  padding-right: 3rem;
}

/* -- Remember me / forgotten password -------------------------------------- */
.siljora-auth__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  margin: var(--space-2) 0 var(--space-5);
}

.woocommerce-account .siljora-auth .woocommerce-form-login__rememberme {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
  cursor: pointer;
}

.woocommerce-account .siljora-auth .woocommerce-form-login__rememberme input {
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
  accent-color: var(--c-text);
}

.ast-single-post .entry-content .woocommerce a.siljora-auth__forgot,
.woocommerce-account a.siljora-auth__forgot {
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.woocommerce-account a.siljora-auth__forgot:hover {
  color: var(--c-text);
}

/* -- Submit ---------------------------------------------------------------- */
.woocommerce-account .siljora-auth .siljora-auth__submit {
  margin: 0;
}

.woocommerce-account .siljora-auth .siljora-auth__submit button.button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 3.125rem;
  margin: 0;
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
}

.woocommerce-account .siljora-auth .woocommerce-privacy-policy-text {
  margin: var(--space-3) 0 var(--space-4);
  font-size: var(--fs-xs);
  line-height: 1.5;
  color: var(--c-text-muted);
}

.woocommerce-account .siljora-auth .siljora-auth__switch,
.siljora-auth__switch {
  margin: var(--space-4) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--c-border-light);
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
}

.ast-single-post .entry-content .woocommerce .siljora-auth__switch a,
.siljora-auth__switch a {
  color: var(--c-text);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Name and phone share a line: four stacked fields made the create-account
   card taller than a laptop screen. They stack again when the panel is narrow. */
.siljora-auth__form--register form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-3);
}

.siljora-auth__form--register form > * {
  grid-column: 1 / -1;
}

@media (min-width: 620px) {
  .siljora-auth__form--register .form-row:has(#siljora_full_name) {
    grid-column: 1;
  }

  .siljora-auth__form--register .form-row:has(#siljora_phone) {
    grid-column: 2;
  }
}

/* -- The panel beside the form --------------------------------------------- */
.siljora-auth__aside {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 100%;
  padding: clamp(var(--space-4), 2.4vw, var(--space-6));
  background: var(--c-surface-muted);
  color: var(--c-text);
  overflow: hidden;
}

.siljora-auth__photo {
  position: absolute;
  inset: 0;
  display: block;
}

.siljora-auth__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Ivory text needs a dark ground to stay legible over any photograph, and the
   gradient keeps the picture visible at the top of the panel. */
.siljora-auth__aside--photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(23, 18, 15, 0.34) 0%, rgba(23, 18, 15, 0.62) 38%, rgba(23, 18, 15, 0.88) 70%, rgba(23, 18, 15, 0.95) 100%);
}

.siljora-auth__aside--photo {
  color: var(--c-on-dark);
}

.siljora-auth__aside-body {
  position: relative;
  z-index: 1;
}

.siljora-auth__eyebrow {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent);
}

.siljora-auth__statement {
  margin: 0 0 var(--space-4);
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.4vw, 1.75rem);
  font-weight: 500;
  font-style: italic;
  line-height: var(--lh-heading);
}

.siljora-auth .siljora-auth__points {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.siljora-auth__points li {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  font-size: var(--fs-sm);
  line-height: 1.5;
}

.siljora-auth__points svg {
  margin-top: 0.2em;
  color: var(--c-accent);
}

.siljora-auth__aside--photo .siljora-auth__points li {
  color: var(--c-on-dark);
}

/* The eyebrow is the smallest text on the photograph, so it gets the ivory
   used elsewhere on dark rather than champagne, which fell below 4.5:1 over
   the lighter part of a picture. */
.siljora-auth__aside--photo .siljora-auth__eyebrow {
  color: var(--c-on-dark);
}

/* The card carries the page's heading ("Sign in" / "Create your account"), so
   Astra's "My account" title above it would be a second h1 saying something
   else. Scoped with :has() to the pages that actually show the card — the
   signed-in dashboard and the Lost password page keep their own titles. */
/* A clear gap under the header, without Astra's full 64px, which pushed the
   card's foot off a laptop screen. */
/* The card sits in a screen-height band, centred, so the footer never peeks
   above the fold on the sign-in page. 100svh keeps it honest on phones, where
   the browser's toolbars come and go. */
.woocommerce-account .entry-content:has(.siljora-auth) {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100svh - 9rem);
  margin-top: 0;
  margin-bottom: var(--space-5);
}

.woocommerce-account .entry-content:has(.siljora-auth) > .siljora-auth {
  width: 100%;
}

.siljora-view-login .site-content:has(.siljora-auth) .entry-header,
.siljora-view-register .site-content:has(.siljora-auth) .entry-header {
  display: none;
}

/* Lost password: the same card, one field wide. */
.woocommerce-account .woocommerce-ResetPassword {
  box-sizing: border-box;
  max-width: 34rem;
  margin: 0 auto;
  padding: clamp(var(--space-5), 4vw, var(--space-7));
  background: var(--c-surface);
  border: 0;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.woocommerce-account .woocommerce-ResetPassword .woocommerce-form-row {
  margin-bottom: var(--space-4);
  padding: 0;
}

.woocommerce-account .woocommerce-ResetPassword label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
}

.woocommerce-account .woocommerce-ResetPassword input.input-text {
  box-sizing: border-box;
  width: 100%;
  height: 3.125rem;
  padding: 0 0.95rem;
  background: var(--c-surface);
  border: 1px solid rgba(31, 26, 22, 0.24);
  border-radius: var(--radius-md);
  font-size: 1rem;
}

.woocommerce-account .woocommerce-ResetPassword input.input-text:focus {
  outline: none;
  border-color: var(--c-text);
  box-shadow: 0 0 0 1px var(--c-text);
}

.woocommerce-account .woocommerce-ResetPassword .form-row-first,
.woocommerce-account .woocommerce-ResetPassword .form-row {
  width: 100%;
  float: none;
  margin-left: 0;
}

.woocommerce-account .woocommerce-ResetPassword button.button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 3.125rem;
  margin: 0;
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
}

/* -- One form at a time ---------------------------------------------------- */
.siljora-view-login .siljora-auth__form--register,
.siljora-view-register .siljora-auth__form--login {
  display: none;
}

@media (max-width: 860px) {
  .woocommerce-account a.siljora-auth__tab {
    min-height: 2.75rem;
  }

  .woocommerce-account .siljora-auth input[type='text'],
  .woocommerce-account .siljora-auth input[type='email'],
  .woocommerce-account .siljora-auth input[type='password'],
  .woocommerce-account .siljora-auth input[type='tel'],
  .woocommerce-account .siljora-auth form .form-row input.input-text {
    height: 3rem;
  }

  .woocommerce-account .siljora-auth .siljora-auth__submit button.button {
    min-height: 3rem;
  }

  .woocommerce-account .siljora-auth {
    grid-template-columns: minmax(0, 1fr);
    max-width: 34rem;
  }

  /* A clear gap under the header, and enough room below the card that the
     footer stays off the first screen on a phone too. */
  .woocommerce-account .entry-content:has(.siljora-auth) {
    margin-top: var(--space-5);
    margin-bottom: var(--space-8);
  }

  /* The photograph leads on a phone, the form follows it. */
  .siljora-auth__aside {
    order: 1;
    min-height: 0;
    aspect-ratio: 16 / 10;
    align-items: flex-end;
  }

  .woocommerce-account .siljora-auth__panel {
    order: 2;
  }
}

@media (prefers-reduced-motion: reduce) {
  .woocommerce-account a.siljora-auth__tab,
  .woocommerce-account .siljora-auth input.input-text {
    transition: none;
  }
}

/* ==========================================================================
   Desktop: the categories dropdown under "Products"
   ==========================================================================
   Built from the shop's own categories (inc/nav-categories.php). Astra's panel
   is a square white box with a 2px rule across the top and 13px rows; this is
   the surface, radius and shadow the rest of the site uses. */

@media (min-width: 922px) {
  .ast-desktop .site-header .main-header-menu .sub-menu {
    min-width: 13rem;
    padding: var(--space-2) 0;
    background-color: var(--c-surface);
    border: 1px solid var(--c-border-light);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
  }

  .ast-desktop .site-header .main-header-menu .sub-menu .menu-item .menu-link {
    padding: var(--space-2) var(--space-4);
    border: 0;
    font-size: 0.8125rem;
    font-weight: 400;
    letter-spacing: var(--ls-label);
    color: var(--c-text);
  }

  .ast-desktop .site-header .main-header-menu .sub-menu .menu-item .menu-link:hover,
  .ast-desktop .site-header .main-header-menu .sub-menu .menu-item .menu-link:focus-visible {
    background-color: var(--c-surface-muted);
    color: var(--c-text);
  }

  .ast-desktop .site-header .main-header-menu .sub-menu .current-menu-item > .menu-link {
    color: var(--c-accent-ink);
  }

  /* The sliding underline belongs to the top bar, not to a list of rows. */
  .ast-desktop .site-header .main-header-menu .sub-menu .menu-link::after {
    content: none;
  }
}

/* ==========================================================================
   Shop pagination
   ==========================================================================
   WooCommerce lays the page numbers out as list items in a full-width list and
   leaves the alignment to the theme; Astra's text-align start left them against
   the first column of products. A centred flex row puts them under the middle
   of the grid, where a shopper looks for them. */

.woocommerce nav.woocommerce-pagination ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: var(--space-6) 0 0;
  padding: 0;
  border: 0;
}

.woocommerce nav.woocommerce-pagination ul li {
  float: none;
  margin: 0;
  border: 0;
}

/* ==========================================================================
   Featured carousel: one screen, whatever the copy says
   ==========================================================================
   The slides were absolutely positioned inside a box whose height was stated
   per breakpoint (460px, then 620, then 440…). That meant two faults at once:
   a longer product description was clipped by the box rather than making it
   taller, and the box was tall enough for the longest description even when
   every product had a short one.

   Stacking the slides in a single grid cell fixes both. The track's height is
   the tallest slide's own height, so nothing is ever cut off and nothing is
   padded out — and the stated heights can go. The hero keeps the old system,
   because its arc swings the slides around and needs them out of the flow. */

.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__track {
  display: grid;
}

.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__viewport,
.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__track {
  min-height: 0;
}

.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__slide {
  position: relative;
  inset: auto;
  grid-area: 1 / 1;
}

/* Sizes for the two-column desktop card. This block sits below the responsive
   blocks above, so it has to exclude phone widths itself — otherwise it wins
   on source order and undoes the phone sizes set earlier. */
@media (min-width: 601px) {
  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__slide {
    padding: 2rem 2.5rem;
    gap: 1.75rem;
  }

  /* The photograph sets most of the card's height, so it is capped before the
     text is. */
  .siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__image {
    max-height: 300px;
  }
}

/* Two lines of description introduce the piece; the product page carries the
   rest. Without the clamp, one long description decides the height of the
   section for every product in it. */
.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__desc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: 0.9rem;
}

.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__name {
  margin-bottom: 0.6rem;
}

.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__price {
  margin-bottom: 1.1rem;
}

.siljora-carousel:not(.siljora-carousel--hero) .siljora-carousel__footer {
  margin-top: 1.1rem;
}

/* ==========================================================================
   Phone header: menu, name, basket
   ==========================================================================
   The three slots are arranged in inc/mobile-header.php — the menu button on
   the left, the logo and name centred, the basket on the right, so the basket
   is visible without opening the menu.

   Astra's basket element is its "outline" style: a 2px square drawn around the
   bag by `.ast-addon-cart-wrap`. The bag reads as a control on its own here, and
   the square fights the menu button opposite it. The count badge needs nothing:
   it already picks up the brand colours from the palette. */

@media (max-width: 921px) {
  .ast-header-break-point .site-header .ast-site-header-cart .ast-addon-cart-wrap {
    border: 0;
    padding: 0;
  }

  /* The same 44px target as the menu button, and the bag optically centred in
     it rather than pushed to the edge of the row. */
  .ast-header-break-point .site-header .ast-site-header-cart .cart-container {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    color: var(--c-text);
  }

  .ast-header-break-point .site-header .ast-site-header-cart i.astra-icon {
    font-size: 1.25rem;
    color: var(--c-text);
  }

  /* Centre slot: the name should sit on the middle of the screen, not the
     middle of what is left over. */
  .ast-header-break-point .site-header .site-header-primary-section-center {
    justify-content: center;
  }

  .ast-header-break-point .site-header .site-header-primary-section-center .site-branding {
    justify-content: center;
  }

  /* The basket is in the bar now, so the row inside the menu would be the same
     control twice. */
  .siljora-has-header-cart.ast-header-break-point .site-header .main-header-menu .siljora-cart-item {
    display: none;
  }
}

/* ==========================================================================
   Phone menu
   ==========================================================================
   Astra's stacked menu gave every entry a 36px row of 12px letterspaced type,
   no separation between entries, and left the Sign Up button collapsed to a
   line of text. These rows are list items you can actually hit: 52px tall,
   readable, hairline-separated, with the current page marked and the account
   button drawn as a button.

   Astra sets the link's display and padding through
   `.ast-header-break-point .main-navigation ul .menu-item .menu-link` (0,4,1),
   so the rules below carry the same prefix plus a class of their own. */

@media (max-width: 921px) {
  .ast-header-break-point .ast-mobile-header-content {
    padding: var(--space-2) 0 var(--space-3);
    background-color: var(--c-surface);
    border-top: 1px solid var(--c-border-light);
    box-shadow: var(--shadow-md);
  }

  /* One row per entry. */
  .ast-header-break-point .site-header .main-header-menu .menu-item > .menu-link,
  .ast-header-break-point .site-header .main-header-menu .siljora-account-toggle {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    box-sizing: border-box;
    width: 100%;
    /* Astra gives menu links `height: 100%`, which stretched the account
       button to cover its whole item once the account list expanded under it. */
    height: auto;
    min-height: 3.5rem;
    padding: var(--space-2) var(--space-5);
    border-bottom: 1px solid var(--c-border-light);
    font-size: 0.9375rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    line-height: 1.3;
    color: var(--c-text);
    transition: background-color var(--t-base) var(--ease-out), color var(--t-base) var(--ease-out);
  }

  .ast-header-break-point .site-header .main-header-menu > .menu-item:last-child > .menu-link {
    border-bottom: 0;
  }

  .ast-header-break-point .site-header .main-header-menu .menu-item > .menu-link:hover,
  .ast-header-break-point .site-header .main-header-menu .menu-item > .menu-link:focus-visible,
  .ast-header-break-point .site-header .main-header-menu .siljora-account-toggle:hover {
    background-color: var(--c-surface-muted);
    color: var(--c-text);
  }

  /* Where you are now: a champagne bar down the leading edge rather than a
     full tint, which read as a hover state that would not go away. */
  .ast-header-break-point .site-header .main-header-menu .current-menu-item > .menu-link,
  .ast-header-break-point .site-header .main-header-menu .current-menu-ancestor > .menu-link {
    box-shadow: inset 3px 0 0 var(--c-accent);
    background-color: var(--c-surface-muted);
    color: var(--c-text);
    font-weight: 500;
  }

  /* The underline animation belongs to the desktop bar; on a row it drew a
     line across the whole width. */
  .ast-header-break-point .site-header .main-header-menu .menu-link::after {
    content: none;
  }

  /* "Products" opens into the shop's categories (see inc/nav-categories.php).
     Astra draws the expand control as a small white tile with its own corner
     radius and shadow, floating at the end of the row; it should read as part
     of the row, and be a 56px target rather than a 44px one. */
  .ast-header-break-point .site-header .main-header-menu .ast-menu-toggle {
    top: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    padding: 0;
    background-color: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    color: var(--c-text);
  }

  .ast-header-break-point .site-header .main-header-menu .ast-menu-toggle .ast-icon {
    transition: transform var(--t-base) var(--ease-out);
  }

  /* Pointing down when closed, up when open: the control says what it will do. */
  .ast-header-break-point .site-header .main-header-menu .ast-menu-toggle[aria-expanded='true'] .ast-icon {
    transform: rotate(180deg);
  }

  /* The categories themselves, indented on the quieter ground already used by
     the account list, so the nesting is legible without a second typeface. */
  .ast-header-break-point .site-header .main-header-menu .siljora-categories-parent > .sub-menu {
    background-color: var(--c-surface-muted);
    border: 0;
    padding: 0;
  }

  .ast-header-break-point .site-header .main-header-menu .siljora-category-item > .menu-link {
    min-height: 3rem;
    padding-left: calc(var(--space-5) + var(--space-5));
    font-size: 0.8125rem;
    color: var(--c-text-muted);
    border-bottom: 0;
  }

  .ast-header-break-point .site-header .main-header-menu .siljora-category-item.current-menu-item > .menu-link {
    color: var(--c-text);
  }

  /* Astra prints a chevron inside every submenu link as well. The indent
     already says these are nested, and a row of arrows pointing nowhere reads
     as four more things to expand.

     It takes this much selector because Astra's own rule is
     `.ast-header-break-point .main-navigation ul .sub-menu
      .menu-item:not(.menu-item-has-children) .menu-link .icon-arrow:first-of-type`
     — (0,8,1) — so a plain `.ast-icon { display: none }` never had a chance. */
  .ast-header-break-point .site-header .main-navigation ul .sub-menu .siljora-category-item:not(.menu-item-has-children) .menu-link .ast-icon.icon-arrow:first-of-type {
    display: none;
  }

  /* Basket: bag, word, then the count out at the end of the row. */
  .ast-header-break-point .site-header .main-navigation ul .siljora-cart-item > .menu-link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
  }

  /* `display: contents` lifts the bag and its count out of their wrapper so
     both become items of the row, which is the only way the count can leave
     the icon's corner and sit at the far end. */
  .ast-header-break-point .site-header .siljora-cart-item .siljora-cart-icon-wrap {
    display: contents;
  }

  .ast-header-break-point .site-header .siljora-cart-item .siljora-cart-icon {
    order: 1;
  }

  .ast-header-break-point .site-header .siljora-cart-item .siljora-cart-label {
    order: 2;
  }

  /* On a row there is space for the count at the far end, where it reads as
     a quantity rather than a badge crowding the bag. */
  .ast-header-break-point .site-header .siljora-cart-item .siljora-cart-count {
    position: static;
    order: 3;
    margin-left: auto;
    box-shadow: none;
  }

  .ast-header-break-point .site-header .siljora-cart-item .menu-link:hover .siljora-cart-icon {
    transform: none;
  }

  /* Astra lays each menu item out as a centred flex row, which shrink-wrapped
     the button to its label in the middle of the list. */
  .ast-header-break-point .site-header .main-header-menu .siljora-account-item {
    display: block;
  }

  /* Sign Up reads as the one action in the list, so it is drawn as a button
     with room around it rather than a fourth line of text. */
  .ast-header-break-point .site-header .main-header-menu .siljora-account-item > .siljora-account-button,
  .ast-header-break-point .site-header .main-header-menu .siljora-account-item > .siljora-account-button:hover,
  .ast-header-break-point .site-header .main-header-menu .siljora-account-item > .siljora-account-button:focus {
    justify-content: center;
    width: auto;
    min-height: 3rem;
    margin: var(--space-4) var(--space-5) var(--space-2);
    padding: 0 var(--space-5);
    border: 1px solid var(--c-text);
    border-radius: var(--radius-md);
    background-color: var(--c-text);
    color: var(--c-text-inverse);
    font-weight: 500;
  }

  .ast-header-break-point .site-header .main-header-menu .siljora-account-item > .siljora-account-button:hover {
    background-color: var(--c-dark);
    border-color: var(--c-dark);
  }

  /* Signed in: the name row opens the account list under it. */
  .ast-header-break-point .site-header .siljora-account-item--user > .siljora-account-menu {
    margin: 0;
    padding: var(--space-2) 0;
    border-left: 0;
    background-color: var(--c-surface-muted);
  }

  .ast-header-break-point .site-header .siljora-account-menu__link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 3rem;
    padding: var(--space-2) var(--space-5) var(--space-2) calc(var(--space-5) + var(--space-5));
    font-size: 0.8125rem;
    letter-spacing: 0.06em;
    color: var(--c-text-muted);
  }

  .ast-header-break-point .site-header .siljora-account-menu__link:hover,
  .ast-header-break-point .site-header .siljora-account-menu__link:focus-visible {
    color: var(--c-text);
    background-color: var(--c-surface);
  }

  /* The toggle that opens and closes all this. */
  .ast-header-break-point .menu-toggle,
  .ast-header-break-point .ast-mobile-menu-trigger-minimal {
    border-radius: var(--radius-md);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ast-header-break-point .site-header .main-header-menu .menu-item > .menu-link {
    transition: none;
  }
}

/* ==========================================================================
   Variation swatches (plugin: Variation Swatches for WooCommerce)
   ==========================================================================
   The plugin renders the attribute dropdown as buttons or colour discs. It is
   driven almost entirely by custom properties with hard-coded fallbacks
   (white fill, black 2px ring, 30px squares), so most of this file is simply
   handing it the site's values.

   Where a property does not exist — the corner radius, the padding — the
   selector has to beat `.woo-variation-swatches .variable-items-wrapper
   .variable-item:not(.radio-variable-item)` (0,4,0). Note `woo-variation-swatches`
   is a class on <body>, not a wrapper, so it is written as `body.woo-variation-swatches`. */

html:root {
  --wvs-single-product-item-width: 2.75rem;
  --wvs-single-product-item-height: 2.75rem;
  --wvs-single-product-item-font-size: 0.9375rem;
  --wvs-archive-product-item-width: 2rem;
  --wvs-archive-product-item-height: 2rem;

  --wvs-item-background-color: var(--c-surface);
  --wvs-item-text-color: var(--c-text);
  --wvs-item-box-shadow: 0 0 0 1px rgba(31, 26, 22, 0.24);

  --wvs-hover-item-background-color: var(--c-surface);
  --wvs-hover-item-text-color: var(--c-text);
  --wvs-hover-item-box-shadow: 0 0 0 1px var(--c-text);

  --wvs-selected-item-background-color: var(--c-text);
  --wvs-selected-item-text-color: var(--c-text-inverse);
  --wvs-selected-item-box-shadow: 0 0 0 1px var(--c-text);
}

/* The attribute's name, in the same voice as a form label. */
.woocommerce div.product .variations th.label,
.woocommerce div.product .variations .label label {
  margin: 0 0 var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-text);
}

body.woo-variation-swatches .variable-items-wrapper {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  line-height: 1;
  cursor: pointer;
  transition: box-shadow var(--t-base) var(--ease-out), background-color var(--t-base) var(--ease-out),
    color var(--t-base) var(--ease-out);
}

/* The plugin's shape rule carries its style class too
   (`.woo-variation-swatches .wvs-style-squared.variable-items-wrapper …`, 0,5,0),
   so the radius has to be restated at that weight or higher. */
body.woo-variation-swatches .variable-items-wrapper.wvs-style-squared .variable-item:not(.radio-variable-item),
body.woo-variation-swatches .variable-items-wrapper.wvs-style-rounded .variable-item:not(.radio-variable-item).button-variable-item {
  border-radius: var(--radius-md);
}

body.woo-variation-swatches .variable-items-wrapper.wvs-style-squared .variable-item:not(.radio-variable-item).color-variable-item,
body.woo-variation-swatches .variable-items-wrapper.wvs-style-squared .variable-item:not(.radio-variable-item).image-variable-item {
  border-radius: var(--radius-pill);
}

body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item):focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 2px;
}

/* Colour and image swatches are discs: the colour is the label, so it must not
   be covered by the selected fill — the ring goes outside it instead. */
body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).color-variable-item,
body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).image-variable-item {
  padding: 0;
  border-radius: var(--radius-pill);
}

body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).color-variable-item .variable-item-span,
body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).image-variable-item .variable-item-span {
  border-radius: var(--radius-pill);
}

body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).color-variable-item.selected,
body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).image-variable-item.selected {
  background-color: transparent;
  box-shadow: 0 0 0 2px var(--c-text), inset 0 0 0 2px var(--c-surface);
}

/* Unavailable with the current choices. The plugin crosses these through with
   a red SVG; a quiet fade with a rule through it belongs to this palette. */
html:root {
  --wvs-cross: none;
}

body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).no-stock,
body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).disabled {
  position: relative;
  opacity: 0.4;
  cursor: not-allowed;
}

body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).no-stock::after,
body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item).disabled::after {
  content: '';
  position: absolute;
  inset: 50% 8% auto;
  height: 1px;
  background: var(--c-text);
}

/* "Clear" reset link under the swatches. Astra's woocommerce-grid.min.css
   fades this to 60% (`.woocommerce-js div.product form.cart .reset_variations`,
   which is (0,4,2)), turning the muted colour's 5.9:1 into about 3:1 at 12px —
   a contrast failure no colour token can explain, because the computed colour
   is innocent and only the opacity is at fault. Naming form.cart as well beats
   it. The fade goes, the colour stays. */
.ast-single-post .entry-content .woocommerce div.product .variations .reset_variations,
.woocommerce div.product .variations .reset_variations,
.woocommerce div.product form.cart .variations .reset_variations {
  display: inline-block;
  margin-top: var(--space-2);
  font-size: var(--fs-xs);
  color: var(--c-text-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  opacity: 1;
}

/* Link to the ring-size guide (see inc/swatches.php). */
.siljora-size-guide {
  margin: 0 0 var(--space-4);
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
}

.ast-single-post .entry-content .woocommerce .siljora-size-guide a,
.siljora-size-guide a {
  color: var(--c-text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.woocommerce div.product .variations {
  margin-bottom: var(--space-4);
}

.woocommerce div.product .woocommerce-variation-price {
  margin: var(--space-3) 0;
}

.woocommerce div.product .woocommerce-variation-availability p {
  margin: 0 0 var(--space-3);
  font-size: var(--fs-sm);
  color: var(--c-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  body.woo-variation-swatches .variable-items-wrapper .variable-item:not(.radio-variable-item) {
    transition: none;
  }
}

/* ==========================================================================
   Editor palette and type sizes on the page
   ==========================================================================
   A block set to a palette colour or a preset size is saved with a class —
   has-siljora-white-color, has-display-font-size — and nothing else. Block
   themes generate the matching CSS from theme.json; a classic theme like this
   one has to write it, or the choice made in the editor simply does nothing on
   the front (which is how the campaign hero first rendered: white heading
   markup, espresso text over a photograph).

   These carry !important because that is what core does for the same classes:
   a colour picked by hand is a deliberate override of whatever the theme sets
   for that element. The slugs and values must stay in step with
   siljora_editor_palette() in inc/landing.php. */

.has-siljora-espresso-color { color: #1f1a16 !important; }
.has-siljora-ink-color { color: #645a52 !important; }
.has-siljora-champagne-color { color: #c0a062 !important; }
.has-siljora-champagne-ink-color { color: #7f6231 !important; }
.has-siljora-rose-color { color: #c2988c !important; }
.has-siljora-blush-color { color: #f1ded9 !important; }
.has-siljora-bg-color { color: #f5f0e9 !important; }
.has-siljora-sand-color { color: #ece4d9 !important; }
.has-siljora-white-color { color: #ffffff !important; }

.has-siljora-espresso-background-color { background-color: #1f1a16 !important; }
.has-siljora-ink-background-color { background-color: #645a52 !important; }
.has-siljora-champagne-background-color { background-color: #c0a062 !important; }
.has-siljora-champagne-ink-background-color { background-color: #7f6231 !important; }
.has-siljora-rose-background-color { background-color: #c2988c !important; }
.has-siljora-blush-background-color { background-color: #f1ded9 !important; }
.has-siljora-bg-background-color { background-color: #f5f0e9 !important; }
.has-siljora-sand-background-color { background-color: #ece4d9 !important; }
.has-siljora-white-background-color { background-color: #ffffff !important; }

.has-siljora-espresso-border-color { border-color: #1f1a16 !important; }
.has-siljora-ink-border-color { border-color: #645a52 !important; }
.has-siljora-champagne-border-color { border-color: #c0a062 !important; }
.has-siljora-champagne-ink-border-color { border-color: #7f6231 !important; }
.has-siljora-rose-border-color { border-color: #c2988c !important; }
.has-siljora-blush-border-color { border-color: #f1ded9 !important; }
.has-siljora-bg-border-color { border-color: #f5f0e9 !important; }
.has-siljora-sand-border-color { border-color: #ece4d9 !important; }
.has-siljora-white-border-color { border-color: #ffffff !important; }

/* Preset sizes. Headings keep the display face; body text does not. */
.has-small-font-size { font-size: 0.9375rem; }
.has-normal-font-size { font-size: 1.0625rem; }
.has-large-font-size { font-size: 1.5rem; }
.has-heading-font-size { font-size: 2.125rem; }
.has-display-font-size { font-size: 3.25rem; }

@media (max-width: 782px) {
  .has-display-font-size { font-size: 2.375rem; }
  .has-heading-font-size { font-size: 1.75rem; }
}

/* ==========================================================================
   Landing pages (page-landing.php)
   ==========================================================================
   Campaign pages built in the block editor: no shop navigation, the brand mark
   at the top, policies at the foot. Content is constrained to the site's
   measure, and blocks set to full width break out of it. */

/* Astra gives #primary a 2rem margin. It has nothing to collapse against here,
   so it escapes the content wrapper and leaves a cream band under the header
   and above the footer — visible, because a campaign hero is full-bleed and is
   meant to meet the header edge. Campaign sections carry their own rhythm. */
.siljora-landing .siljora-landing__content #primary#primary {
  margin: 0;
}

/* Ordinary blocks sit on the site's measure and centred; a block set to full
   width in the editor breaks out of it, which is what the hero and the closing
   panel do. Without this the heading between two full-bleed sections sits at
   the left edge of whatever width Astra happens to give the article. */
.siljora-landing .entry-content > *:not(.alignfull):not(.alignwide) {
  max-width: var(--container);
  margin-left: auto;
  margin-right: auto;
}

.siljora-landing .entry-content > .alignwide {
  max-width: min(100%, 1400px);
  margin-left: auto;
  margin-right: auto;
}

/* Section headings inside a campaign page. Full-bleed sections bring their own
   padding, so only the headings between them need rhythm. */
.siljora-landing .entry-content > .wp-block-heading {
  margin: var(--space-8) 0 var(--space-5);
}

.siljora-landing .entry-content > .wp-block-cover + .wp-block-heading {
  margin-top: var(--space-7);
}

.siljora-landing__header {
  display: flex;
  justify-content: center;
  padding: var(--space-5) var(--gutter);
  background: var(--c-bg);
  border-bottom: 1px solid var(--c-border-light);
}

.siljora-landing__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
}

.siljora-landing__logo {
  width: auto;
  height: 40px;
}

.siljora-landing__name {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--c-text);
}

.siljora-landing__content {
  background: var(--c-bg);
}

.siljora-landing .entry-content {
  max-width: none;
  margin: 0;
}

/* The measure for ordinary blocks; anything set to full width ignores it. */
.siljora-landing .entry-content > *,
.siljora-landing .entry-content > .wp-block-group > :where(:not(.alignfull)) {
  max-width: 72rem;
  margin-inline: auto;
}

.siljora-landing .entry-content > .alignfull {
  max-width: none;
  width: 100%;
  margin-inline: 0;
}

.siljora-landing .entry-content > .alignwide {
  max-width: 84rem;
}

/* Sections the shop already owns (carousels, promise strip) bring their own
   padding, so they need no measure of their own. */
.siljora-landing .entry-content > .siljora-section,
.siljora-landing .entry-content > section {
  max-width: none;
}

.siljora-landing .entry-content > .wp-block-group,
.siljora-landing .entry-content > .wp-block-cover {
  padding-block: clamp(var(--space-7), 8vw, var(--space-9));
  padding-inline: var(--gutter);
}

.siljora-landing__footer {
  padding: var(--space-6) var(--gutter) var(--space-7);
  background: var(--c-dark);
  color: var(--c-on-dark-muted);
  text-align: center;
}

.siljora-landing__footer .siljora-checkout__policies {
  margin: 0 auto;
  padding: 0;
  border: 0;
}

.siljora-landing__footer .siljora-checkout__policies ul {
  justify-content: center;
}

.siljora-landing__footer .siljora-checkout__policies a {
  color: var(--c-on-dark-muted);
}

.siljora-landing__footer .siljora-checkout__policies a:hover {
  color: var(--c-on-dark);
}

.siljora-landing__copyright {
  margin: var(--space-4) 0 0;
  font-size: var(--fs-xs);
  color: var(--c-on-dark-muted);
}
