

@font-face {
    font-family: 'Bauhaus Apex';
    src: url('fonts/bauhaus-apex-black.woff') format('woff'),
         url('fonts/bauhaus-apex-black.otf') format('opentype');
    font-weight: 900;
    font-style: normal;
    font-display: swap;
  }
  @font-face {
    font-family: 'Bauhaus Apex';
    src: url('fonts/bauhaus-apex-black.woff') format('woff'),
         url('fonts/bauhaus-apex-black.otf') format('opentype');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
  }
  @font-face {
    font-family: 'Limoncello Recipe';
    src: url('fonts/limoncello-recipe.woff') format('woff'),
         url('fonts/limoncello-recipe.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
  }

  :root {
    --bg: #0c0c0c;
    --fg: #ededed;
    --muted: #8a8a8a;
    --accent: #c8322d;
    --rose: #c9a4a0;
    --hairline: rgba(255, 255, 255, 0.08);
  }

  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  html {
    scroll-behavior: smooth;
    scroll-padding-top: 6rem;
    background: var(--bg);
  }

  body {
    background: var(--bg);
    color: var(--fg);
    font-family: 'Libre Franklin', -apple-system, sans-serif;
    font-weight: 400;
    line-height: 1.5;
    overflow-x: hidden;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
  }

  /* ============ NAV ============ */
  /* Top site nav only — scope to direct child of body so this doesn't
     leak into other <nav> landmarks elsewhere in the page (e.g. the
     homepage filter pills used to inherit position:fixed from this
     before they were moved to a div). */
  .site-nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 50;
    padding: 1.5rem 2.5rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: linear-gradient(to bottom, rgba(12,12,12,0.95), rgba(12,12,12,0.6) 70%, transparent);
    backdrop-filter: blur(6px);
  }

  .nav-mark {
    display: flex;
    align-items: baseline;
    text-decoration: none;
    line-height: 1;
    gap: 0.25rem;
  }

  .nav-mark .mark-coven {
    font-family: 'Bauhaus Apex', sans-serif;
    font-weight: 900;
    font-size: 2.25rem;
    letter-spacing: -0.02em;
    color: transparent;
    -webkit-text-stroke: 1.25px var(--accent);
    paint-order: stroke fill;
    line-height: 0.9;
  }

  .nav-mark .mark-sf {
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: 2rem;
    color: var(--fg);
    line-height: 0.9;
    margin-left: 0.1rem;
  }

  .nav-links {
    display: flex;
    gap: 1.75rem;
    list-style: none;
  }

  .nav-links a {
    font-family: 'Archivo', sans-serif;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    color: var(--fg);
    text-decoration: none;
    font-weight: 600;
    text-transform: uppercase;
    position: relative;
    transition: color 0.3s ease;
    padding-bottom: 4px;
  }

  .nav-links a::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .nav-links a:hover::after {
    transform: scaleX(1);
  }

  .nav-links .nav-craft { color: var(--craft); }
  .nav-links .nav-lore { color: var(--lore); }
  .nav-links .nav-canon { color: var(--canon); }
  .nav-links .nav-offering { color: var(--offering); }
  .nav-links .nav-contact { color: var(--contact); }

  .nav-links .nav-craft::after { background: var(--craft); }
  .nav-links .nav-lore::after { background: var(--lore); }
  .nav-links .nav-canon::after { background: var(--canon); }
  .nav-links .nav-offering::after { background: var(--offering); }
  .nav-links .nav-contact::after { background: var(--contact); }

  /* ============ HERO ============ */
  .hero {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    /* Push content down from top instead of centering vertically, so the
       headline sits below the fixed nav with room to breathe. The padding
       scales with viewport height to feel right on any screen size. */
    justify-content: flex-start;
    padding: max(14rem, 22vh) 4rem 9rem;
    max-width: 1400px;
    margin: 0 auto;
  }

  h1.headline {
    color: var(--fg);
    margin-bottom: 3rem;
    line-height: 0.95;
    opacity: 0;
    animation: manifest 2.0s cubic-bezier(0.16, 1, 0.3, 1) 0.2s forwards;
  }

  .headline-coven {
    display: block;
    font-family: 'Bauhaus Apex', sans-serif;
    font-weight: 900;
    font-size: clamp(6rem, 16vw, 14rem);
    letter-spacing: -0.02em;
    line-height: 0.85;
    margin-bottom: -0.1em;
    color: var(--accent);
  }

  .headline-rest {
    display: block;
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: clamp(3.5rem, 8vw, 7.25rem);
    line-height: 1.05;
    letter-spacing: 0;
    text-transform: none;
    color: var(--fg);
  }

  .headline-rest-mobile {
    display: none;
  }

  .headline-rest .line {
    display: block;
    white-space: nowrap;
  }

  .headline-rest .accent-word {
    color: var(--fg);
  }

  .descriptor {
    font-family: 'Limoncello Recipe', cursive;
    font-size: clamp(2rem, 3.2vw, 2.75rem);
    line-height: 1.35;
    color: var(--rose);
    max-width: 48rem;
    font-weight: 400;
    opacity: 0;
    animation: manifest 1.8s cubic-bezier(0.16, 1, 0.3, 1) 0.7s forwards;
  }

  .descriptor strong {
    color: var(--rose);
    font-weight: 400;
  }

  .descriptor + .descriptor {
    margin-top: 1.25rem;
    animation-delay: 0.7s;
  }

  /* "manifest" — subtle reveal that reads as conjuring rather than
     arriving from off-screen. A tiny scale settles (1.015 → 1) plus
     opacity fade-in. No translate, no blur. Reads as the words
     resolving in place, which fits the spell-shop voice better than
     a generic slide-up. */
  @keyframes manifest {
    to {
      opacity: 1;
      transform: scale(1);
    }
  }

  @keyframes fadeUpTilted {
    to {
      opacity: 1;
      transform: translateY(0) rotate(-1.2deg);
    }
  }

  h1.headline, .descriptor {
    transform: scale(1.015);
  }

  /* ============ FOOTER ============ */
  /* ===== SITE FOOTER ===== */
  .site-footer {
    border-top: 1px solid var(--hairline);
    margin-top: 0.5rem;
  }
  .footer-inner {
    max-width: 1400px;
    margin: 0 auto;
    padding: 3rem 4rem 2.5rem;
    display: flex;
    gap: 3rem;
    align-items: flex-start;
  }
  /* The two right-side columns cluster together; brand sits on the left.
     justify-content: space-between on the flex parent pushes them apart,
     but we group contact + follow inside a sub-wrapper... actually no,
     simpler: just flex-grow the brand so the two right columns nestle. */
  .footer-brand {
    margin-right: auto;
    /* Center the tagline under the 'coven' logo. Both items are flex
       children of .footer-col (flex-direction: column), so align-items
       center aligns them horizontally within the column's content box. */
    align-items: center;
  }
  /* HTML order is brand -> contact -> meta (follow), but we want the
     display order on desktop to be brand -> follow -> contact. Use
     flex `order` to swap contact and meta without moving markup. */
  .footer-meta {
    order: 2;
  }
  .footer-contact {
    order: 3;
  }
  .footer-col {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
  }
  .footer-logo {
    font-family: 'Bauhaus Apex', sans-serif;
    font-weight: 900;
    font-size: 3rem;
    line-height: 0.85;
    color: var(--accent);
    letter-spacing: -0.02em;
  }
  .footer-tagline {
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: 1.5rem;
    color: var(--fg);
    max-width: 22rem;
    line-height: 1.1;
    margin-top: -0.5rem;
  }
  .footer-label {
    font-family: 'Archivo', sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 0.3rem;
  }
  .footer-link {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.95rem;
    font-weight: 300;
    color: var(--fg);
    text-decoration: none;
    transition: color 160ms ease;
  }
  .footer-link:hover {
    color: var(--contact);
  }

  /* Social icons sit in the footer-meta column. Muted by default, shift
     to violet on hover to match the other footer-link affordances. */
  .footer-socials {
    display: flex;
    gap: 0.9rem;
    align-items: center;
  }
  .footer-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--fg);
    text-decoration: none;
    transition: color 160ms ease, transform 160ms ease;
  }
  .footer-social:hover {
    color: var(--contact);
  }
  .footer-social-icon {
    display: block;
  }

  @media (max-width: 900px) {
    .footer-inner {
      /* Override desktop flex — revert to grid for the mobile stack. */
      display: grid;
      grid-template-columns: 1fr 1fr;
      padding: 2.5rem 1.5rem 2rem;
      gap: 2rem;
    }
    .footer-brand {
      grid-column: 1 / -1;
      margin-right: 0;
      /* Mobile lockup: the brand block sits left-aligned in its column
         (matching contact + follow columns below). The wordmark + tagline
         pair is centered RELATIVE TO EACH OTHER inside .footer-brand-lockup,
         but the whole lockup unit is left-aligned to the page. So
         "San Francisco" is centered horizontally under "coven", while the
         pair as a whole anchors to the left edge.
         (Earlier we had align-items: center which centered the WHOLE
         lockup against the viewport — visually nice but inconsistent with
         the contact+follow columns below it.) */
      align-items: flex-start;
      text-align: left;
    }
    /* Reset the desktop flex-order swap — mobile uses DOM order. */
    .footer-meta,
    .footer-contact {
      order: 0;
    }
  }
  @media (max-width: 640px) {
    .footer-inner {
      grid-template-columns: 1fr;
    }
  }

  /* ============ RESPONSIVE ============ */
  @media (max-width: 900px) {
    .site-nav {
      padding: 1rem 1.5rem;
    }
    .nav-mark .mark-coven {
      font-size: 1.5rem;
    }
    .nav-mark .mark-sf {
      font-size: 1.35rem;
    }
    .nav-links {
      gap: 1.25rem;
    }
    .nav-links a {
      font-size: 0.7rem;
    }
    .hero {
      padding: 9rem 1.5rem 1rem;
      /* Override the desktop min-height: 100vh. At tablet widths the
         raven is width-anchored (smaller height than the bird at desktop)
         and the headline is also smaller — so 100vh produces empty
         space below the bird before The Craft section begins.
         min-height accommodates the absolute-positioned raven (which
         doesn't contribute to the parent's natural height) while
         closing the void below it. Bottom padding tightened from 4rem
         to 1rem so the next section (.section-craft hairline) sits
         right under the bird's branch with minimal gap. */
      min-height: 36rem;
    }
    .headline-coven {
      font-size: clamp(4rem, 20vw, 7rem);
    }
    .headline-rest {
      font-size: clamp(2.5rem, 11vw, 4rem);
    }
    footer {
      flex-direction: column;
      align-items: start;
      gap: 0.75rem;
      padding: 2rem 1.5rem;
    }
  }


  /* ============ SECTIONS ============ */
  :root {
    --craft: #e8b04a;     /* amber gold — alchemy, honey, candlelight */
    --spells: #e8b04a;    /* alias for --craft (The Spells page uses the same gold) */
    --lore: #7fb8a8;      /* sage teal — herbs, moss, old glass */
    --canon: #d4826a;     /* terracotta — ink, rust, old book spines */
    --offering: #8ea9d4;  /* pale indigo — moonlight, cold tea (reserved for The Shop) */
    --contact: #a77dc4;   /* violet — smoke, twilight, crystal */
  }

  .section {
    padding: 6rem 4rem;
    max-width: 1400px;
    margin: 0 auto;
    border-top: 1px solid var(--hairline);
  }

  .section-inner {
    position: relative;
  }

  .section-number {
    font-family: 'Archivo', sans-serif;
    font-weight: 600;
    font-size: 0.8125rem;
    letter-spacing: 0.2em;
    color: var(--muted);
    display: block;
    margin-bottom: 2rem;
  }

  .section-title {
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: clamp(2.25rem, 4.5vw, 4rem);
    line-height: 1.05;
    letter-spacing: 0;
    color: currentColor;
    -webkit-text-stroke: 0.4px currentColor;
    paint-order: stroke fill;
    margin-bottom: 1.75rem;
  }

  .section-craft .section-title,
  .section-craft .section-number { color: var(--craft); }
  .section-lore .section-title,
  .section-lore .section-number { color: var(--lore); }
  .section-canon .section-title,
  .section-canon .section-number { color: var(--canon); }
  .section-offering .section-title,
  .section-offering .section-number { color: var(--offering); }
  .section-contact .section-title,
  .section-contact .section-number { color: var(--contact); }

  .section-body {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1.125rem;
    line-height: 1.6;
    color: var(--fg);
    max-width: 54rem;
    font-weight: 300;
    margin-bottom: 1.75rem;
  }

  .section-body:last-child {
    margin-bottom: 0;
  }

  .section-offerings {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--fg);
    max-width: 54rem;
    font-weight: 300;
    margin: 2rem 0 2rem;
    padding: 1.75rem 0;
    border-top: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
  }

  .section-craft .section-offerings {
    border-color: rgba(232, 176, 74, 0.3);
  }

  .offerings-label {
    font-family: 'Archivo', sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--craft);
    font-weight: 700;
    display: block;
    margin-bottom: 0.5rem;
  }

  .section-tiers {
    font-family: 'Libre Franklin', sans-serif;
    max-width: 54rem;
    margin: 0.5rem 0 0;
    padding: 1.75rem 0 0;
  }

  .tiers-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
  }

  /* Menu-row layout: square icon well on the left, stacked name + description
     on the right. Dividers between rows via border-top on all but the first. */
  .tier {
    display: grid;
    grid-template-columns: 6rem 1fr;
    gap: 1.75rem;
    align-items: center;
    padding: 1.75rem 0;
    border-top: 1px solid rgba(232, 176, 74, 0.18);
  }

  .tier:first-child {
    border-top: none;
  }

  .tier-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--craft);
    opacity: 0.85;
  }
  .tier-icon svg {
    width: 100%;
    max-width: 5rem;
    height: auto;
    display: block;
  }
  .tier-icon-img {
    width: 100%;
    max-width: 5rem;
    height: auto;
    display: block;
  }

  .tier-text {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }

  .tier-name {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 500;
    font-size: 1.25rem;
    line-height: 1.2;
    letter-spacing: -0.005em;
    text-transform: none;
    color: var(--craft);
  }

  .tier-tag {
    display: inline-block;
    margin-left: 0.5rem;
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: 1.0625rem;
    letter-spacing: 0;
    text-transform: none;
    color: var(--fg);
    opacity: 0.6;
  }

  .tier-desc {
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--fg);
    opacity: 0.88;
    font-weight: 300;
  }

  /* ============ LORE BLOCKS ============ */
  .lore-block {
    max-width: 54rem;
    margin: 2rem 0;
    padding: 1.75rem 0;
    border-top: 1px solid var(--hairline);
  }

  /* Gold-tinted separator on the Craft page so the hairline matches the
     section's accent color rather than the neutral white hairline. */
  .section-craft .lore-block {
    border-color: rgba(232, 176, 74, 0.3);
  }

  .section-lore .lore-block {
    border-color: rgba(127, 184, 168, 0.25);
  }

  .section-lore .offerings-label {
    color: var(--lore);
    margin-bottom: 1.25rem;
  }

  /* Coven list */
  .coven-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: 1.25rem 2rem;
  }

  .coven-member {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
  }

  /* Logo grid */
  .logo-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-top: 0.5rem;
  }

  .logo-slot {
    aspect-ratio: 16 / 9;
    border: 1px dashed rgba(127, 184, 168, 0.3);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Archivo', sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--lore);
    opacity: 0.55;
    text-align: center;
    padding: 0.5rem;
    line-height: 1.3;
    word-break: normal;
    overflow-wrap: break-word;
    overflow: hidden;
  }

  @media (max-width: 720px) {
    .logo-grid {
      grid-template-columns: repeat(2, 1fr);
      gap: 0.75rem;
    }
    .logo-slot {
      aspect-ratio: 5 / 3;
      padding: 0.75rem;
    }
  }

  /* Projects list */
  .projects-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
  }

  .project {
    display: grid;
    grid-template-columns: 14rem 1fr;
    gap: 2rem;
    align-items: baseline;
    padding: 1.25rem 0;
    border-top: 1px solid rgba(127, 184, 168, 0.15);
  }

  .project:first-child {
    border-top: none;
    padding-top: 0;
  }

  .project-brand {
    font-family: 'Archivo', sans-serif;
    font-weight: 700;
    font-size: 0.9375rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--lore);
  }

  .project-meta {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
  }

  .project-title {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 500;
    font-size: 1.0625rem;
    color: var(--fg);
    display: block;
    margin-bottom: 0.25rem;
  }

  .project-desc {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--fg);
    opacity: 0.75;
    font-weight: 300;
    display: block;
  }

  @media (max-width: 720px) {
    .project {
      grid-template-columns: 1fr;
      gap: 0.5rem;
    }
    .project-brand {
      font-size: 0.875rem;
    }
  }



  .logo-slot svg,
  .logo-slot img {
    /* Explicit rem-based heights rather than % of the aspect-ratio container.
       Safari has intermittent bugs where percentage max-height doesn't resolve
       inside an aspect-ratio flex container, causing logos to render at their
       intrinsic size. Concrete rem values are honored consistently. */
    height: 2.75rem;
    max-height: 2.75rem;
    width: auto;
    max-width: 75%;
    display: block;
    object-fit: contain;
  }

  /* Tall/square logos (Apple glyph, Airbnb mark, AKQA serif block,
     Twitter bird) would dwarf the wide wordmarks at a matched height.
     Tighten their cap so all logos read at a similar optical weight. */
  .logo-slot.logo-apple svg,
  .logo-slot.logo-airbnb img,
  .logo-slot.logo-akqa img,
  .logo-slot.logo-twitter img {
    height: 2rem;
    max-height: 2rem;
    max-width: 60%;
  }

  @media (max-width: 720px) {
    .logo-slot svg,
    .logo-slot img {
      height: 2.25rem;
      max-height: 2.25rem;
      width: auto;
      max-width: 80%;
    }
    .logo-slot.logo-apple svg,
    .logo-slot.logo-airbnb img,
    .logo-slot.logo-akqa img,
    .logo-slot.logo-twitter img {
      height: 1.6rem;
      max-height: 1.6rem;
      max-width: 60%;
    }
    .logo-slot.logo-netflix img,
    .logo-slot.logo-google img,
    .logo-slot.logo-lucid img {
      height: 1.5rem;
      max-height: 1.5rem;
    }
  }

  /* Style all real logos consistently */
  .logo-slot.logo-sftravel,
  .logo-slot.logo-apple,
  .logo-slot.logo-airbnb,
  .logo-slot.logo-google,
  .logo-slot.logo-netflix,
  .logo-slot.logo-akqa,
  .logo-slot.logo-lucid,
  .logo-slot.logo-twitter {
    color: var(--fg);
    opacity: 0.9;
    border-style: solid;
    border-color: rgba(127, 184, 168, 0.2);
  }

  /* Values list */
  .values-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
  }

  .value {
    display: grid;
    grid-template-columns: 14rem 1fr;
    gap: 2rem;
    align-items: baseline;
    padding-top: 1.25rem;
    border-top: 1px solid rgba(127, 184, 168, 0.15);
  }

  .value:first-child {
    border-top: none;
    padding-top: 0;
  }

  .value-name {
    font-family: 'Archivo', sans-serif;
    font-weight: 700;
    font-size: 0.9375rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--lore);
  }

  .value-desc {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1rem;
    line-height: 1.6;
    color: var(--fg);
    opacity: 0.9;
    font-weight: 300;
  }

  @media (max-width: 720px) {
    .value {
      grid-template-columns: 1fr;
      gap: 0.5rem;
    }
    .value-name {
      font-size: 0.875rem;
    }
  }

  @media (max-width: 720px) {
    .tier {
      grid-template-columns: 3rem 1fr;
      gap: 1rem;
      align-items: start;
    }
    .tier-icon svg,
    .tier-icon-img {
      max-width: 2.75rem;
    }
  }

  .section-disclaimer {
    font-size: 0.875rem;
    line-height: 1.55;
    color: var(--craft);
    font-style: italic;
    opacity: 0.85;
    margin-top: 0.25rem;
  }

  .section-placeholder {
    font-family: 'Archivo', sans-serif;
    font-size: 0.8125rem;
    letter-spacing: 0.1em;
    color: var(--muted);
    text-transform: uppercase;
    padding: 2rem;
    border: 1px dashed var(--hairline);
    border-radius: 2px;
    display: inline-block;
  }

  .section-craft .section-placeholder { border-color: rgba(232, 176, 74, 0.25); color: var(--craft); }
  .section-lore .section-placeholder { border-color: rgba(127, 184, 168, 0.25); color: var(--lore); }
  .section-canon .section-placeholder { border-color: rgba(212, 130, 106, 0.25); color: var(--canon); }
  .section-offering .section-placeholder { border-color: rgba(142, 169, 212, 0.25); color: var(--offering); }
  .section-contact .section-placeholder { border-color: rgba(167, 125, 196, 0.25); color: var(--contact); }

  @media (max-width: 900px) {
    .section {
      padding: 5rem 1.5rem;
    }
    .section-title {
      font-size: clamp(1.75rem, 7vw, 2.5rem);
    }
    .section-body {
      font-size: 1.0625rem;
    }
  }



  /* ============ HERO RAVEN ============ */
  .hero {
    position: relative;
    overflow: hidden;
  }

  /* Default: desktop/laptop — raven is a hero element, the bird's body runs
     alongside the headline. We size by HEIGHT so the vertical proportions
     stay consistent: bird's head sits near the top, branch extends to the
     bottom, image spans the viewport height. Right-anchored to the hero
     container (which caps at 1400px and centers), so the raven always
     lives next to the headline rather than drifting to the far edge of
     very wide monitors. */
  .hero-raven {
    position: absolute;
    bottom: 0;
    top: auto;
    right: -4%;
    left: auto;
    transform: none;
    /* 95vh: the raven fills the viewport vertically — head with a small
       breathing margin above, branch resting near the bottom edge. This
       is what keeps the bird & headline feeling like peers instead of the
       bird towering above or sitting below the copy. */
    width: auto;
    height: 95vh;
    max-width: none;
    z-index: 1;
    pointer-events: none;
    opacity: 0.82;
    filter: brightness(0.82) saturate(0.4);
    animation: ravenFade 2.9s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards;
  }

  /* Very tall viewports: cap to keep the raven from towering over the
     headline (which caps at 14rem). */
  @media (min-height: 1100px) {
    .hero-raven {
      height: min(95vh, 1100px);
    }
  }

  /* The raven materializes through opacity rather than sliding in
     from the right. Pairs with the headline's "manifest" keyframes
     — both feel like things resolving into view rather than
     arriving from off-screen. */
  @keyframes ravenFade {
    from {
      opacity: 0;
    }
    to {
      opacity: 0.82;
    }
  }

  .hero > *:not(.hero-raven) {
    position: relative;
    z-index: 2;
  }

  /* Pull the headline back so it overlaps the raven */
  h1.headline {
    position: relative;
    z-index: 3;
  }

  /* "coven" should sit in front of the raven, "is a spell shop" behind it */
  .headline-rest {
    position: relative;
    z-index: 1;
  }

  .headline-coven {
    position: relative;
    z-index: 3;
  }




  .inline-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid rgba(127, 184, 168, 0.4);
    transition: border-color 0.25s ease, color 0.25s ease;
    padding-bottom: 1px;
  }

  .inline-link:hover {
    color: var(--lore);
    border-bottom-color: var(--lore);
  }



  /* Tablet / small desktop */
  @media (max-width: 900px) {
    .nav-links {
      gap: 1rem;
    }
    .nav-links a {
      font-size: 0.7rem;
      letter-spacing: 0.01em;
    }
    /* Scale the raven by width on tablet — letting height auto-compute
       from the image's natural 1.5 aspect ratio. The desktop rule sets
       height: 95vh which on tablet conflicts with the new width
       constraint and stretches the bird. Resetting height to auto fixes
       the proportions.

       Anchoring: previously bottom:0 on tablet, but the width-clamp
       produces a bird that's shorter than the hero — so bottom:0 made
       the bird sink into the lower-right corner separated from the
       headline. Anchor from top instead (matching where the headline
       starts) so the bird and headline overlap as visual peers, the
       same relationship desktop has. The branch may extend below the
       hero on shorter viewports, which is fine — overflow is hidden. */
    .hero-raven {
      left: auto;
      right: -8%;
      top: 5rem;
      bottom: auto;
      width: clamp(560px, 90%, 880px);
      height: auto;
      opacity: 0.7;
    }
  }

  /* Phone */
  @media (max-width: 640px) {
    .site-nav {
      padding: 1rem 1rem;
      flex-wrap: wrap;
      gap: 0.75rem;
    }
    .nav-mark .mark-coven {
      font-size: 1.35rem;
    }
    .nav-links {
      width: 100%;
      gap: 0.75rem;
      justify-content: flex-start;
      flex-wrap: wrap;
    }
    .nav-links a {
      font-size: 0.65rem;
      letter-spacing: 0.06em;
    }
    .hero {
      padding: 6rem 1.25rem 0.5rem 1.25rem;
      min-height: 95vh;
      display: flex;
      flex-direction: column;
      justify-content: flex-end;
    }
    .hero-raven {
      position: absolute;
      left: 50%;
      right: auto;
      top: 4rem;
      bottom: auto;
      transform: translateX(-60%);
      width: auto;
      max-width: none;
      height: 95vh;
      margin: 0;
      opacity: 0.78;
      filter: brightness(0.62) saturate(0.5);
      animation: ravenFadeMobile 2.9s cubic-bezier(0.16, 1, 0.3, 1) 0.4s backwards;
      z-index: 1;
      pointer-events: none;
    }
    /* Mobile raven materializes via opacity, matching the desktop
       manifest behavior. Keeps the translateX(-60%) since that's
       the resting position (raven offset behind copy), not part of
       the entrance motion. */
    @keyframes ravenFadeMobile {
      from {
        opacity: 0;
        transform: translateX(-60%);
      }
      to {
        opacity: 0.78;
        transform: translateX(-60%);
      }
    }
    .headline-coven {
      font-size: clamp(4.5rem, 28vw, 7rem);
      -webkit-text-stroke-width: 2px;
    }
    .headline-rest-desktop {
      display: none;
    }
    .headline-rest-mobile {
      display: block;
    }
    .headline-rest {
      font-size: clamp(3.75rem, 20vw, 6.5rem);
      padding-bottom: 0.35em;
    }
    .headline-rest .line {
      white-space: nowrap;
    }
    /* Cursive "shop in SF" has wide initial/final swashes; shrink a touch
       and add left/right padding so glyphs don't clip at the viewport edge */
    .headline-rest-mobile .line.accent-word {
      font-size: 0.82em;
      padding-left: 0.15em;
      padding-right: 0.15em;
    }
    .section {
      padding: 4.5rem 1.25rem;
    }
    /* Subpages: first section sits directly under the fixed two-row mobile nav.
       Give it extra top padding so the section-title isn't hidden on landing. */
    nav + .section,
    nav + main > .section:first-child {
      padding-top: 8.5rem;
    }
    .section-title {
      font-size: clamp(1.75rem, 9vw, 2.5rem);
    }
    .section-body {
      font-size: 1rem;
      line-height: 1.6;
    }
    .section-offerings {
      font-size: 1rem;
    }
    .offerings-label {
      font-size: 0.65rem;
      letter-spacing: 0.14em;
    }
    .tier {
      grid-template-columns: 2.5rem 1fr;
      gap: 0.75rem;
      padding-top: 1rem;
      align-items: start;
    }
    .tier-icon {
      grid-row: span 2;
    }
    .tier-icon svg,
    .tier-icon-img {
      max-width: 2.25rem;
    }
    .tier-desc {
      font-size: 0.9375rem;
    }
    .value {
      grid-template-columns: 1fr;
      gap: 0.5rem;
    }
    .project {
      grid-template-columns: 1fr;
      gap: 0.5rem;
      padding: 1rem 0;
    }
    .logo-grid {
      grid-template-columns: repeat(2, 1fr);
      gap: 0.625rem;
    }
    .section-disclaimer {
      font-size: 0.8125rem;
    }
    footer {
      padding: 2rem 1.25rem;
      gap: 0.5rem;
    }
  }



  .coven-image {
    margin: 1rem 0 2.5rem;
    max-width: 54rem;
    overflow: hidden;
    border-radius: 4px;
    position: relative;
  }

  .coven-image img {
    width: 100%;
    height: auto;
    display: block;
    filter: brightness(0.9) saturate(0.75);
  }

  .coven-image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(12,12,12,0.4) 0%, transparent 40%);
    pointer-events: none;
  }



  .origin-label {
    display: block;
    margin-top: 2rem;
    margin-bottom: 1rem;
  }

  .section-lore .origin-label {
    color: var(--lore);
  }



  /* ============================================================
     CHARMED HEART — SCRAPBOOK CLIPPING
     The original photo has a dark page-matching background already,
     so it reads as a heart cutout against the body of the page.
     We just float-right + tilt slightly + apply shape-outside on a
     heart path so the prose wraps to the curve of the heart rather
     than the rectangular bounding box. No SVG re-cropping needed —
     the heart already exists inside the photo.
     ============================================================ */
  .charmed-heart {
    float: right;
    width: clamp(140px, 18vw, 200px);
    height: auto;
    margin: -0.5rem 0 0.5rem 1.5rem;
    /* Heart-shaped text wrap: prose hugs the curve of the heart
       rather than its rectangular bounding box. The path matches the
       silhouette of the heart inside the photo (slightly inset from
       the photo's edge to give text a small breathing margin). */
    shape-outside: path("M50,85 C50,85 8,58 8,30 C8,16 20,6 33,6 C42,6 47,10 50,17 C53,10 58,6 67,6 C80,6 92,16 92,30 C92,58 50,85 50,85 Z");
    shape-margin: 0.5rem;
    transform: rotate(-3deg);
    transform-origin: 50% 50%;
    /* Subtle period-photo treatment: slight desat so it reads as a
       fan clipping rather than a fresh stock image. */
    filter: saturate(0.7) brightness(0.9);
  }

  @media (max-width: 640px) {
    .charmed-heart {
      width: 110px;
      margin: 0 0 0.5rem 1rem;
    }
  }



  /* ============ SPELLBOOK SHOP ============ */

  .shop-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 2rem 0 3rem;
    flex-wrap: wrap;
  }

  .shop-meta .offerings-label {
    color: var(--offering);
    margin: 0;
  }

  .shop-meta-text {
    font-family: 'Archivo', sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg);
    opacity: 0.65;
  }

  .shop-meta-divider {
    color: var(--offering);
    opacity: 0.5;
    font-size: 0.75rem;
  }

  .spell-grid {
    display: grid;
    /* minmax(0, 1fr) prevents content-intrinsic sizing from making columns
       uneven — e.g. the bundle card's wide image column trying to widen its
       track and stealing fr space from siblings. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1rem;
    margin-top: 1rem;
  }

  /* ===== Suggest a spell form ===== */
  .suggest-spell {
    max-width: 36rem;
    margin: 5rem 0 0;
    padding-top: 3rem;
    border-top: 1px solid rgba(142, 169, 212, 0.18);
  }
  .suggest-spell-title {
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: clamp(1.35rem, 2.2vw, 1.75rem);
    line-height: 1.2;
    color: var(--offering);
    margin: 0 0 1.25rem;
  }
  .suggest-spell-form textarea {
    width: 100%;
    background: transparent;
    border: 1px solid rgba(142, 169, 212, 0.28);
    color: var(--fg);
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.95rem;
    font-weight: 300;
    font-style: italic;
    padding: 0.85rem 1rem;
    border-radius: 0;
    outline: none;
    resize: vertical;
    min-height: 5rem;
    line-height: 1.5;
    transition: border-color 160ms ease, background 160ms ease;
    -webkit-appearance: none;
    appearance: none;
  }
  .suggest-spell-form textarea:focus {
    border-color: var(--offering);
    background: rgba(142, 169, 212, 0.04);
  }
  .suggest-spell-form textarea::placeholder {
    color: var(--muted);
    opacity: 0.7;
    font-style: italic;
  }
  .suggest-spell-submit {
    margin-top: 1.25rem;
    background: transparent;
    color: var(--offering);
    border: 1px solid var(--offering);
    font-family: 'Archivo', sans-serif;
    font-size: 0.8rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    font-weight: 700;
    padding: 0.95rem 1.75rem;
    cursor: pointer;
    transition: background 160ms ease, color 160ms ease, transform 160ms ease;
  }
  .suggest-spell-submit:hover {
    background: var(--offering);
    color: #0c0c0c;
  }
  .suggest-spell-submit:active {
    transform: translateY(1px);
  }
  .suggest-spell-success {
    margin-top: 1.25rem;
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.95rem;
    font-weight: 300;
    color: var(--offering);
    font-style: italic;
  }
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  /* ===== Coven around town ===== */
  /* Subsection on the spells page, below the suggest-a-spell form. */
  .coven-around-town {
    margin: 5rem 0 0;
    padding-top: 3rem;
    border-top: 1px solid rgba(142, 169, 212, 0.18);
    display: grid;
    /* Image column narrower than copy column — the vending machine is tall &
       narrow, and a 1:1 split makes it feel dominant with a huge empty zone
       next to it. Center-aligned vertically so the copy sits at the midpoint
       of the image rather than hugging the top (which leaves dead air below). */
    grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
    gap: 3rem;
    align-items: center;
  }
  /* Cap the copy column at a comfortable reading width (~60-70ch) so the body
     text and list items don't stretch edge-to-edge on wide monitors. Applied
     to the wrapper so every child inherits the constraint uniformly. */
  .coven-around-town-copy {
    max-width: 36rem;
  }
  .coven-around-town-title {
    font-family: 'Limoncello Recipe', cursive;
    font-weight: 400;
    font-size: clamp(1.35rem, 2.2vw, 1.75rem);
    line-height: 1.2;
    color: var(--offering);
    margin: 0 0 1.25rem;
  }
  .coven-around-town-body {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1.0625rem;
    font-weight: 300;
    line-height: 1.6;
    color: var(--fg);
    opacity: 0.85;
    margin: 0 0 2rem;
  }
  .coven-around-town .offerings-label {
    color: var(--offering);
    margin-bottom: 0.75rem;
  }
  .coven-locations {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .coven-locations li {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1rem;
    font-weight: 300;
    line-height: 1.45;
    color: var(--fg);
    opacity: 0.85;
    padding-left: 1.25rem;
    position: relative;
  }
  .coven-locations li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.55em;
    width: 0.4rem;
    height: 0.4rem;
    background: var(--offering);
    opacity: 0.55;
    border-radius: 50%;
  }
  .coven-around-town-image {
    position: relative;
    margin: 0;
    line-height: 0;
    max-width: 18rem;
    width: 100%;
  }
  .coven-around-town-image img {
    display: block;
    width: 100%;
    height: auto;
  }
  .coven-around-town-image .spell-fpo {
    top: 0.55rem;
    right: 0.55rem;
  }
  /* Stack vertically on narrower viewports */
  @media (max-width: 780px) {
    .coven-around-town {
      grid-template-columns: minmax(0, 1fr);
      gap: 2rem;
      margin: 4rem 0 0;
      padding-top: 2.5rem;
    }
    /* Smaller, centered vending machine on mobile. The image's natural
       aspect (666x1000) is tall, so letting it scale to full container
       width was creating a huge vertical block that dominated the
       viewport. Cap at 14rem and center to give it the size of a
       photo-illustration rather than a hero asset. The copy below
       carries the section. */
    .coven-around-town-image {
      max-width: 14rem;
      margin: 0 auto;
    }
  }

  @media (max-width: 1100px) {
    .spell-grid {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
  }

  @media (max-width: 780px) {
    .spell-grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }
  /* Intentionally no 1-column fallback below 480px — 2 cards per row
     scans better at phone sizes than a single column. If card internals
     feel too tight, adjust gap or card padding in the grid at this size. */


  .spell-card {
    position: relative;
    background: #0c0c0c;
    border: 1px solid rgba(168, 125, 196, 0.18);
    display: flex;
    flex-direction: column;
    transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1),
                border-color 0.3s ease;
    height: 100%;
  }

  .spell-card:hover {
    transform: translateY(-4px);
    border-color: rgba(168, 125, 196, 0.45);
  }

  .spell-cover {
    aspect-ratio: 5 / 7;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.75rem;
    position: relative;
    overflow: hidden;
    text-align: center;
  }

  .spell-cover-title {
    position: relative;
    z-index: 2;
  }

  /* Image-based spell cover. Real art fills edge-to-edge; overrides the
     padded/centered treatment of typographic placeholder covers. */
  .cover-image {
    padding: 0;
  }
  .spell-cover-image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    position: relative;
    z-index: 1;
  }

  .spell-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.875rem 1rem 1rem;
    border-top: 1px solid rgba(168, 125, 196, 0.15);
    gap: 0.75rem;
    flex-shrink: 0;
  }

  .spell-number {
    font-family: 'Archivo', sans-serif;
    font-size: 0.65rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--fg);
    opacity: 0.4;
    flex-shrink: 0;
  }

  .spell-price {
    font-family: 'Archivo', sans-serif;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--fg);
    letter-spacing: 0.02em;
  }

  .add-btn {
    font-family: 'Archivo', sans-serif;
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    background: transparent;
    color: var(--craft);
    border: 1px solid rgba(232, 176, 74, 0.68);
    padding: 0.5rem 0.9rem;
    cursor: pointer;
    transition: all 0.2s ease;
    white-space: nowrap;
  }

  .add-btn:hover {
    background: var(--craft);
    color: #0c0c0c;
    border-color: var(--craft);
  }

  .add-btn.added {
    background: var(--craft);
    color: #0c0c0c;
    border-color: var(--craft);
  }

  /* ===== FPO PLACEHOLDER TAG ===== */
  /* Marks every spell card as "For Placement Only" while final art is in progress. */
  .spell-fpo {
    position: absolute;
    top: 0.55rem;
    right: 0.55rem;
    z-index: 5;
    font-family: 'Archivo', sans-serif;
    font-size: 0.58rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    padding: 0.2rem 0.45rem;
    color: #111;
    background: #f4c542;
    border-radius: 2px;
    pointer-events: none;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  }

  /* ===== SPELL CARD COVER VARIATIONS ===== */
  /* Each card gets a distinct typographic/layout treatment to hint at how the actual printed objects will look different. */

  /* Style 1: Bold all-caps display, left-aligned */
  .cover-style-1 {
    background: #0c0c0c;
    align-items: flex-end;
    justify-content: flex-start;
    text-align: left;
    padding: 2rem;
  }
  .cover-style-1 .spell-cover-title {
    font-family: 'Bauhaus Apex Display', sans-serif;
    font-weight: 900;
    font-size: clamp(1.5rem, 3.5vw, 2.25rem);
    line-height: 0.92;
    letter-spacing: -0.01em;
    color: var(--contact);
    text-transform: uppercase;
  }

  /* Style 2: Ornate script, centered on parchment-like tone */
  .cover-style-2 {
    background: radial-gradient(circle at 50% 40%, rgba(232, 176, 74, 0.08), transparent 70%);
  }
  .cover-style-2 .spell-cover-title {
    font-family: 'Limoncello Recipe', cursive;
    font-size: clamp(1.5rem, 3.5vw, 2.5rem);
    color: var(--craft);
    line-height: 1.05;
  }

  /* Style 3: Stark editorial, tight justified block */
  .cover-style-3 {
    background: #0c0c0c;
    align-items: center;
    justify-content: center;
    padding: 2rem;
  }
  .cover-style-3 .spell-cover-title {
    font-family: 'Libre Franklin', serif;
    font-weight: 200;
    font-size: clamp(1.35rem, 2.8vw, 1.85rem);
    letter-spacing: 0.02em;
    line-height: 1.15;
    font-style: italic;
    color: #ededed;
  }

  /* Style 4: Red brutalist, massive single word stacked */
  .cover-style-4 {
    background: #0c0c0c;
    align-items: flex-start;
    justify-content: flex-start;
    text-align: left;
    padding: 1.75rem;
  }
  .cover-style-4 .spell-cover-title {
    font-family: 'Bauhaus Apex Display', sans-serif;
    font-weight: 900;
    font-size: clamp(2rem, 5.5vw, 3.25rem);
    line-height: 0.88;
    letter-spacing: -0.02em;
    color: var(--accent);
    text-transform: lowercase;
  }

  /* Style 5: Symmetrical sigil, type circles a mark */
  .cover-style-5 {
    background: #0c0c0c;
  }
  .cover-style-5 .spell-cover-title {
    font-family: 'Archivo', sans-serif;
    font-weight: 500;
    font-size: clamp(0.95rem, 2vw, 1.15rem);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    line-height: 1.4;
    color: var(--lore);
  }
  .cover-style-5::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 45%;
    aspect-ratio: 1;
    border: 1px solid var(--lore);
    border-radius: 50%;
    opacity: 0.35;
  }

  /* Style 6: Huge italic serif, diagonal feel */
  .cover-style-6 {
    background: linear-gradient(140deg, #0c0c0c 0%, rgba(200, 50, 45, 0.1) 100%);
    align-items: flex-start;
    text-align: left;
    padding: 1.75rem;
  }
  .cover-style-6 .spell-cover-title {
    font-family: 'Libre Franklin', serif;
    font-weight: 300;
    font-style: italic;
    font-size: clamp(1.5rem, 3.2vw, 2.1rem);
    line-height: 1.05;
    color: var(--rose);
    letter-spacing: -0.01em;
  }

  /* Style 7: Label / apothecary bottle feel */
  .cover-style-7 {
    background: #0c0c0c;
  }
  .cover-style-7 .spell-cover-title {
    font-family: 'Archivo', sans-serif;
    font-weight: 700;
    font-size: clamp(1rem, 2.2vw, 1.25rem);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #ededed;
    line-height: 1.3;
    padding: 0.9rem 1.1rem;
    border-top: 2px solid var(--craft);
    border-bottom: 2px solid var(--craft);
    margin: 0 0.5rem;
  }

  /* Style 8: Handwritten on grid */
  .cover-style-8 {
    background-color: #0c0c0c;
    background-image:
      linear-gradient(rgba(168, 125, 196, 0.06) 1px, transparent 1px),
      linear-gradient(90deg, rgba(168, 125, 196, 0.06) 1px, transparent 1px);
    background-size: 20px 20px;
  }
  .cover-style-8 .spell-cover-title {
    font-family: 'Limoncello Recipe', cursive;
    font-size: clamp(1.65rem, 3.5vw, 2.4rem);
    color: var(--contact);
    line-height: 1.05;
    transform: rotate(-2deg);
  }

  /* Style 9: Ransom note asterisks around tight caps */
  .cover-style-9 {
    background: #0c0c0c;
  }
  .cover-style-9 .spell-cover-title {
    font-family: 'Bauhaus Apex Display', sans-serif;
    font-weight: 700;
    font-size: clamp(1.1rem, 2.4vw, 1.5rem);
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #ededed;
    line-height: 1.1;
  }
  .cover-style-9::before {
    content: "✷";
    position: absolute;
    top: 1.25rem;
    left: 1.25rem;
    color: var(--accent);
    font-size: 1.25rem;
  }
  .cover-style-9::after {
    content: "✷";
    position: absolute;
    bottom: 1.25rem;
    right: 1.25rem;
    color: var(--accent);
    font-size: 1.25rem;
  }

  /* Style 10: Centered sage, small Roman numeral above */
  .cover-style-10 {
    background: linear-gradient(180deg, #0c0c0c 0%, rgba(127, 184, 168, 0.08) 100%);
    flex-direction: column;
    gap: 1rem;
  }
  .cover-style-10 .spell-cover-title {
    font-family: 'Libre Franklin', serif;
    font-weight: 300;
    font-size: clamp(1.3rem, 2.7vw, 1.75rem);
    line-height: 1.2;
    color: var(--lore);
    letter-spacing: -0.01em;
  }
  .cover-style-10::before {
    content: "★";
    position: absolute;
    top: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    color: var(--lore);
    font-size: 0.9rem;
    opacity: 0.5;
  }

  /* Style 11: Massive lowercase script */
  .cover-style-11 {
    background: #0c0c0c;
    align-items: flex-end;
    text-align: left;
    padding: 1.75rem;
  }
  .cover-style-11 .spell-cover-title {
    font-family: 'Limoncello Recipe', cursive;
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 0.95;
    color: var(--craft);
  }

  /* Style 12: Tight block, all caps, tiny accent line */
  .cover-style-12 {
    background: #0c0c0c;
  }
  .cover-style-12 .spell-cover-title {
    font-family: 'Archivo', sans-serif;
    font-weight: 800;
    font-size: clamp(1.15rem, 2.5vw, 1.55rem);
    letter-spacing: -0.005em;
    text-transform: uppercase;
    line-height: 1.05;
    color: #ededed;
    position: relative;
  }
  .cover-style-12::after {
    content: "";
    position: absolute;
    bottom: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    width: 1.5rem;
    height: 2px;
    background: var(--accent);
  }

  /* ===== CART ===== */
  .cart-trigger {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: 40;
    background: var(--craft);
    color: #0c0c0c;
    border: none;
    padding: 0.875rem 1.25rem;
    font-family: 'Archivo', sans-serif;
    font-weight: 600;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05);
    transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.3s ease;
    opacity: 0;
    pointer-events: none;
    transform: translateY(8px);
  }

  .cart-trigger.visible {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }

  .cart-trigger:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 50px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08);
  }

  .cart-count {
    background: #0c0c0c;
    color: var(--craft);
    min-width: 1.4rem;
    height: 1.4rem;
    padding: 0 0.4rem;
    border-radius: 100px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
  }

  .cart-drawer {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(420px, 100vw);
    background: #0a0a0a;
    border-left: 1px solid rgba(168, 125, 196, 0.2);
    z-index: 60;
    transform: translateX(100%);
    transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
    display: flex;
    flex-direction: column;
  }

  .cart-drawer.open {
    transform: translateX(0);
  }

  .cart-drawer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.5rem;
    border-bottom: 1px solid rgba(168, 125, 196, 0.15);
  }

  .cart-drawer-title {
    font-family: 'Limoncello Recipe', cursive;
    font-size: 1.75rem;
    color: var(--craft);
  }

  .cart-close {
    background: none;
    border: none;
    color: var(--fg);
    font-size: 1.5rem;
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    line-height: 1;
    opacity: 0.6;
    transition: opacity 0.2s;
  }
  .cart-close:hover { opacity: 1; }

  .cart-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
  }

  .cart-empty {
    font-family: 'Libre Franklin', sans-serif;
    font-weight: 300;
    color: var(--fg);
    opacity: 0.5;
    text-align: center;
    padding: 3rem 1rem;
    line-height: 1.6;
  }
  .cart-empty span {
    font-family: 'Limoncello Recipe', cursive;
    font-size: 1.25rem;
    color: var(--craft);
    opacity: 0.8;
  }

  /* Cart item layout — two rows, two columns. Explicit grid-row
     pinning so children don't auto-flow into wrong cells.
       Row 1: Title (left)                Price (right)            ✕ tucked top-right corner
       Row 2: [− N +] (left)
     Removed the text Remove button — the ✕ in the corner is the
     universal "remove this" affordance. */
  .cart-item {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    column-gap: 1rem;
    row-gap: 0.5rem;
    padding: 1rem 1.5rem 1rem 0;
    border-bottom: 1px solid rgba(168, 125, 196, 0.08);
    align-items: center;
    position: relative;
  }

  .cart-item-title {
    grid-column: 1;
    grid-row: 1;
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.95rem;
    font-weight: 400;
    color: var(--fg);
    line-height: 1.3;
  }

  .cart-item-price {
    grid-column: 2;
    grid-row: 1;
    font-family: 'Archivo', sans-serif;
    font-size: 0.875rem;
    color: var(--fg);
    opacity: 0.85;
    font-weight: 500;
    text-align: right;
  }

  /* ✕ tucked into the top-right corner of each line item. Small and
     low-opacity so it reads as a discreet affordance, not a button
     competing with the price for attention. */
  .cart-item-x {
    position: absolute;
    top: -0.75rem;
    right: -0.25rem;
    width: 1.25rem;
    height: 1.25rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.5;
    transition: opacity 0.15s, color 0.15s;
    padding: 0;
  }
  .cart-item-x:hover {
    opacity: 1;
    color: var(--accent);
  }

  /* Quantity stepper — left column, row 2, paired with the price
     (right column, same row). Compact so the cart line stays
     scannable. */
  .cart-item-qty {
    grid-column: 1;
    grid-row: 2;
    justify-self: start;
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .cart-item-qty-btn {
    width: 1.5rem;
    height: 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: var(--fg);
    font-family: 'Archivo', sans-serif;
    font-size: 0.875rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    transition: border-color 0.15s, color 0.15s, opacity 0.15s;
  }
  .cart-item-qty-btn:hover:not(:disabled) {
    border-color: var(--accent);
    color: var(--accent);
  }
  .cart-item-qty-btn:disabled {
    opacity: 0.3;
    cursor: not-allowed;
  }
  .cart-item-qty-count {
    min-width: 1ch;
    text-align: center;
    font-family: 'Archivo', sans-serif;
    font-size: 0.875rem;
    color: var(--fg);
  }

  .cart-drawer-footer {
    border-top: 1px solid rgba(168, 125, 196, 0.15);
    padding: 1.25rem 1.5rem 1.75rem;
    background: rgba(168, 125, 196, 0.02);
  }

  .cart-total-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-family: 'Archivo', sans-serif;
    font-size: 0.75rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg);
    opacity: 0.8;
    margin-bottom: 1rem;
  }
  .cart-total-row span:last-child {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1.25rem;
    opacity: 1;
    letter-spacing: 0;
    text-transform: none;
    font-weight: 500;
  }

  .checkout-btn {
    width: 100%;
    font-family: 'Archivo', sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    background: var(--craft);
    color: #0c0c0c;
    border: none;
    padding: 1rem;
    cursor: not-allowed;
    opacity: 0.5;
  }

  .cart-footer-note {
    margin-top: 0.75rem;
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.75rem;
    color: var(--fg);
    opacity: 0.4;
    text-align: center;
    line-height: 1.5;
    font-weight: 300;
  }

  .cart-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(4px);
    opacity: 0;
    pointer-events: none;
    z-index: 50;
    transition: opacity 0.3s ease;
  }
  .cart-backdrop.visible {
    opacity: 1;
    pointer-events: auto;
  }



  /* ===== BUNDLE CARD ===== */
  .spell-card-bundle {
    border-color: rgba(168, 125, 196, 0.45);
    background: linear-gradient(155deg, #0c0c0c 0%, rgba(168, 125, 196, 0.08) 100%);
    /* Endcap the row: 2 cols on desktop (4-col grid), full width on tablet/mobile */
    grid-column: span 2;
  }

  @media (max-width: 1100px) {
    .spell-card-bundle {
      grid-column: 1 / -1;
    }
  }

  .spell-card-bundle:hover {
    border-color: var(--offering);
  }

  /* When the bundle stretches horizontally, it needs an aspect ratio
     that keeps its cover the same height as sibling spell-card covers
     (which are 3:4 portrait at ~1 column width). At 2-col span, that
     means 3:2 landscape — visually aligned with neighbors in the row. */
  .spell-card-bundle .spell-cover {
    aspect-ratio: 3 / 2;
    min-height: 0;
  }

  .cover-bundle {
    display: grid;
    grid-template-columns: minmax(14rem, 22rem) 1fr;
    align-items: center;
    gap: 2.25rem;
    text-align: left;
    padding: 1.75rem 2.25rem;
    background: linear-gradient(135deg, rgba(168, 125, 196, 0.12), transparent 70%);
  }

  .bundle-cover-image {
    display: block;
    width: 100%;
    height: auto;
    max-height: 100%;
    object-fit: contain;
    filter: drop-shadow(0 12px 24px rgba(0, 0, 0, 0.5));
    position: relative;
    z-index: 2;
  }

  .bundle-cover-copy {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    position: relative;
    z-index: 2;
  }

  /* Stack vertically on narrower viewports (image on top, copy below) */
  @media (max-width: 780px) {
    .cover-bundle {
      grid-template-columns: 1fr;
      gap: 1.25rem;
      padding: 2rem 1.75rem;
      justify-items: center;
      text-align: center;
    }
    .bundle-cover-image {
      max-height: 17rem;
      max-width: 14rem;
    }
    .bundle-cover-copy {
      align-items: center;
    }
  }

  .bundle-cover-eyebrow {
    font-family: 'Archivo', sans-serif;
    font-size: 0.65rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--offering);
    opacity: 0.85;
    position: relative;
    z-index: 2;
  }

  .bundle-cover-title {
    font-family: 'Bauhaus Apex Display', sans-serif;
    font-weight: 900;
    font-size: clamp(2rem, 4vw, 2.75rem);
    line-height: 0.95;
    color: var(--offering);
    letter-spacing: -0.01em;
    position: relative;
    z-index: 2;
    margin-bottom: 0.25rem;
  }

  .bundle-cover-sub {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.8rem;
    font-weight: 300;
    line-height: 1.45;
    color: var(--fg);
    opacity: 0.7;
    position: relative;
    z-index: 2;
    margin-top: 0.25rem;
  }

  /* ===== HOMEPAGE TEASER SPACING ===== */
  /* Teaser sections on the homepage sit closer together than full pages */
  .lore-teaser,
  .spellbook-teaser,
  .section-shop-teaser,
  .contact-teaser {
    padding-top: 5rem;
    padding-bottom: 5rem;
  }
  /* When a full section precedes a teaser, tighten its bottom padding to match */
  .section:has(+ .lore-teaser),
  .section:has(+ .spellbook-teaser),
  .section:has(+ .section-shop-teaser),
  .section:has(+ .contact-teaser) {
    padding-bottom: 5rem;
  }

  /* ===== HOMEPAGE SPELLBOOK TEASER ===== */
  .spellbook-teaser {
    border-top: 1px solid var(--hairline);
  }
  .spell-grid-teaser {
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
  }
  /* Mobile teaser: 2 cards per row (2x2 grid). At narrower widths the
     teaser drops directly from 4-col to 2-col without any awkward 3-col
     middle state, which would leave 1 card alone in row 2. */
  @media (max-width: 780px) {
    .spell-grid-teaser {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }
  .spell-grid-teaser .spell-cover {
    padding: 1rem;
  }
  .spell-grid-teaser .spell-cover-title,
  .spell-grid-teaser .cover-style-1 .spell-cover-title,
  .spell-grid-teaser .cover-style-2 .spell-cover-title,
  .spell-grid-teaser .cover-style-3 .spell-cover-title,
  .spell-grid-teaser .cover-style-4 .spell-cover-title,
  .spell-grid-teaser .cover-style-5 .spell-cover-title,
  .spell-grid-teaser .cover-style-6 .spell-cover-title,
  .spell-grid-teaser .cover-style-7 .spell-cover-title,
  .spell-grid-teaser .cover-style-8 .spell-cover-title,
  .spell-grid-teaser .cover-style-9 .spell-cover-title,
  .spell-grid-teaser .cover-style-10 .spell-cover-title,
  .spell-grid-teaser .cover-style-11 .spell-cover-title,
  .spell-grid-teaser .cover-style-12 .spell-cover-title {
    font-size: 0.65rem;
    line-height: 1.15;
  }
  .spell-grid-teaser .spell-meta {
    padding: 0.5rem 0.65rem 0.6rem;
    gap: 0.4rem;
  }
  .spell-grid-teaser .spell-number {
    font-size: 0.55rem;
  }
  .spell-grid-teaser .spell-price {
    font-size: 0.75rem;
  }
  .spell-grid-teaser .add-btn {
    font-size: 0.55rem;
    padding: 0.3rem 0.55rem;
    letter-spacing: 0.1em;
  }
  /* Teaser cards are too small for anything but the title; tighten FPO tag. */
  .spell-grid-teaser .spell-fpo {
    font-size: 0.48rem;
    padding: 0.15rem 0.35rem;
    top: 0.4rem;
    right: 0.4rem;
    letter-spacing: 0.12em;
  }
  .teaser-link {
    display: inline-block;
    margin-top: 2rem;
    font-family: 'Archivo', sans-serif;
    font-size: 0.8rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--offering);
    text-decoration: none;
    border-bottom: 1.5px solid rgba(142, 169, 212, 0.7);
    padding-bottom: 0.3rem;
    transition: color 160ms ease, border-color 160ms ease;
  }
  .teaser-link:hover {
    color: #b0c5e3;
    border-color: var(--offering);
  }
  .teaser-link-lore {
    color: var(--lore);
    border-bottom-color: rgba(127, 184, 168, 0.7);
    margin-top: 1.25rem;
  }
  .teaser-link-lore:hover {
    color: #a2cfc1;
    border-color: var(--lore);
  }
  .lore-teaser {
    border-top: 1px solid var(--hairline);
  }

  /* ===== MAKE CONTACT ===== */
  .contact-block {
    padding: 2.5rem 0;
    border-top: 1px solid rgba(167, 125, 196, 0.18);
  }
  .contact-block:first-child {
    margin-top: 1rem;
  }
  .contact-block:last-child {
    border-bottom: 1px solid rgba(167, 125, 196, 0.18);
  }
  .contact-label {
    color: var(--contact);
    margin-bottom: 0.75rem;
  }
  .contact-lede {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1.0625rem;
    line-height: 1.6;
    color: var(--fg);
    font-weight: 300;
    max-width: 44rem;
    margin: 0 0 1.75rem;
  }

  .contact-form {
    max-width: 44rem;
  }
  .field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin-bottom: 1rem;
  }
  .field {
    display: block;
    margin-bottom: 1rem;
  }
  .field-row .field {
    margin-bottom: 0;
  }
  .field-label {
    font-family: 'Archivo', sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    display: block;
    margin-bottom: 0.4rem;
  }
  .contact-form input,
  .contact-form select,
  .contact-form textarea {
    width: 100%;
    background: transparent;
    border: 1px solid rgba(167, 125, 196, 0.28);
    color: var(--fg);
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1rem;
    font-weight: 300;
    padding: 0.85rem 1rem;
    border-radius: 0;
    outline: none;
    transition: border-color 160ms ease, background 160ms ease;
    -webkit-appearance: none;
    appearance: none;
  }
  .contact-form textarea {
    resize: vertical;
    min-height: 7rem;
    line-height: 1.5;
  }
  .contact-form input:focus,
  .contact-form select:focus,
  .contact-form textarea:focus {
    border-color: var(--contact);
    background: rgba(167, 125, 196, 0.04);
  }
  .contact-form input::placeholder,
  .contact-form textarea::placeholder {
    color: var(--muted);
    opacity: 0.7;
  }
  .contact-form select {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%23a77dc4' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    padding-right: 2.5rem;
  }
  .contact-form select option {
    background: var(--bg);
    color: var(--fg);
  }
  .contact-submit {
    margin-top: 1.25rem;
    background: transparent;
    color: var(--contact);
    border: 1px solid var(--contact);
    font-family: 'Archivo', sans-serif;
    font-size: 0.8rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    font-weight: 700;
    padding: 0.95rem 1.75rem;
    cursor: pointer;
    transition: background 160ms ease, color 160ms ease, transform 160ms ease;
  }
  .contact-submit:hover {
    background: var(--contact);
    color: #0c0c0c;
  }
  .contact-submit:active {
    transform: translateY(1px);
  }
  .contact-success {
    margin-top: 1.25rem;
    font-family: 'Libre Franklin', sans-serif;
    font-size: 0.95rem;
    font-weight: 300;
    color: var(--contact);
    font-style: italic;
  }

  /* Send us a raven — direct contact list */
  .raven-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    max-width: 44rem;
  }
  .raven-list li {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
  }
  .raven-label {
    font-family: 'Archivo', sans-serif;
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--contact);
    font-weight: 700;
  }
  .raven-value {
    font-family: 'Libre Franklin', sans-serif;
    font-size: 1.25rem;
    font-weight: 300;
    color: var(--fg);
    text-decoration: none;
    padding-bottom: 0.15rem;
    transition: color 160ms ease, border-color 160ms ease;
    align-self: flex-start;
  }
  .raven-value:hover {
    color: var(--contact);
  }

  /* ===== PAGE BOUNDARY MARKERS =====
     This HTML file is a design spec for a multi-page site.
     These dividers mark where one page ends and another begins
     in the eventual build (Squarespace, etc.). */
  .page-boundary {
    display: flex;
    align-items: center;
    gap: 1.5rem;
    max-width: var(--max);
    margin: 4rem auto;
    padding: 0 var(--pad);
    opacity: 0.5;
  }
  .page-boundary::before,
  .page-boundary::after {
    content: "";
    flex: 1;
    height: 1px;
    background: rgba(255, 255, 255, 0.15);
  }
  .page-boundary-label {
    font-family: 'Archivo', sans-serif;
    font-size: 0.65rem;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
    white-space: nowrap;
  }
  @media (max-width: 640px) {
    .page-boundary {
      margin: 2.5rem auto;
      gap: 1rem;
    }
    .page-boundary-label {
      font-size: 0.58rem;
      letter-spacing: 0.22em;
    }
  }
/* Optical kerning for the "coven" wordmark at display sizes. Bauhaus
   Apex's even-set spacing reads slightly uneven across mixed letter
   shapes at the headline scale — the angular `v` creates visual
   whitespace on its sides that the metrics don't account for, and
   two close-bowled `o`s next to a circular `c` need a hair of
   breathing room to feel even.
   - .kern-o nudges `o` right of `c` by a tiny fraction
   - .kern-v tucks `v` closer to `o` on its left side
   - .kern-e tucks the `e` closer to `v` on its right side
   - .kern-n tightens the final n-pair (existing rule)
   The v needs compensation on BOTH sides because its angled silhouette
   creates triangular whitespace at top and bottom — the type metrics
   center on the bounding box, not the visual mass.
*/
.headline-coven .kern-o,
.footer-logo .kern-o {
  display: inline-block;
  margin-left: 0.012em;
}
.headline-coven .kern-v,
.footer-logo .kern-v {
  display: inline-block;
  margin-left: -0.07em;
}
.headline-coven .kern-e,
.footer-logo .kern-e {
  display: inline-block;
  margin-left: -0.07em;
}
/* Tighten the e-n pair in the "coven" wordmark — reads a touch loose
   at display sizes compared to the rest of the word. */
.headline-coven .kern-n,
.footer-logo .kern-n {
  display: inline-block;
  margin-left: -0.03em;
}
@media (max-width: 640px) {
  .headline-coven .kern-n { margin-left: -0.035em; }
}


/* Craft-section variant of the teaser link (homepage → /craft/).
   Uses the warm gold --craft color and sits tight beneath the
   key-offerings rule so it reads as a direct continuation of it. */
.teaser-link-craft {
  color: var(--craft);
  border-bottom-color: rgba(232, 176, 74, 0.7);
}
.teaser-link-craft:hover {
  color: #f0c776;
  border-color: var(--craft);
}
/* Collapse the vertical gap between the key-offerings block (which
   has its own bottom hairline) and the craft CTA, so the link sits
   right beneath that line instead of floating 4rem below it. */
.section-offerings:has(+ .teaser-link-craft) {
  margin-bottom: 0.75rem;
}
.section-offerings + .teaser-link-craft {
  margin-top: 0;
}

/* Arrow-slide hover. The arrow is wrapped in its own span so it can
   translate independently of the text. 4px on hover is enough to read
   as motion without feeling cartoonish. */
.teaser-arrow {
  display: inline-block;
  margin-left: 0.15em;
  transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.teaser-link:hover .teaser-arrow {
  transform: translateX(4px);
}

/* ============================================================
   "Join the coven" drawer on the Make Contact page.
   Collapses the recruiting form by default — most visitors are
   potential clients, not applicants, so this hides the noise
   without losing the entry point. Mirrors the .discipline
   drawer pattern from the Lore page. Keeps the base
   .contact-block padding/borders so it sits in the same
   visual rhythm as the other blocks on this page. */

.contact-join-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0;
  margin: 0;
  transition: opacity 0.2s ease;
}
.contact-join-summary::-webkit-details-marker { display: none; }
.contact-join-summary:hover { opacity: 0.85; }

/* Cursive subsection title — matches the .suggest-spell-title /
   .coven-around-town-title treatment on the Spells page, but in
   the contact section's purple. */
.contact-join-title {
  font-family: 'Limoncello Recipe', cursive;
  font-weight: 400;
  font-size: clamp(1.35rem, 2.2vw, 1.75rem);
  line-height: 1.2;
  color: var(--contact);
  margin: 0;
}

.contact-join-chevron-DEPRECATED { display: none; }

/* Apply pill — makes the drawer's clickable affordance unambiguous.
   Outlined style (no fill) so it reads as a button but stays quieter
   than the solid "Send it" form submits. */
.contact-join-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: 'Archivo', sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--contact);
  border: 1.5px solid rgba(167, 125, 196, 0.55);
  border-radius: 999px;
  padding: 0.55rem 0.9rem 0.55rem 1rem;
  line-height: 1;
  transition: border-color 180ms ease, background-color 180ms ease;
}
.contact-join-summary:hover .contact-join-toggle {
  border-color: var(--contact);
  background-color: rgba(167, 125, 196, 0.08);
}
.contact-join-toggle-chevron {
  display: inline-block;
  font-weight: 300;
  font-size: 1rem;
  line-height: 1;
  width: 0.8rem;
  text-align: center;
  transition: transform 0.3s ease;
}
.contact-join-drawer[open] .contact-join-toggle-chevron {
  transform: rotate(45deg);
}

/* When open, put a breathing gap between the summary row and
   the revealed lede paragraph. */
.contact-join-drawer[open] .contact-join-summary {
  margin-bottom: 0.75rem;
}

/* ============================================================
   Kit cards on the Spells page — same .spell-card chrome as
   individual spells, but with a grey FPO placeholder cover
   (no product photo yet), "TBD" where a price would be, and
   a disabled "Soon" button. Sits inline in the 4-column grid
   between the 18 spells and the bundle card.
   ============================================================ */

/* Grey placeholder cover. Kit cards span 2 columns in the grid so
   their covers are landscape (3:2) instead of matching the 3:4 portrait
   aspect of single-spell covers. This visually signals "a set, not a
   single spell" and calms the overall rhythm of the kits row. */
.cover-kit {
  background: #1a1a1a;
  border: 1px dashed rgba(255, 255, 255, 0.08);
  aspect-ratio: 3 / 2;
}

/* Title treatment on the kit cover — centered, display type, in the
   muted palette so it reads as "placeholder-with-intent" rather than
   a real cover painting. */
.cover-kit .spell-cover-title {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 500;
  font-size: clamp(0.95rem, 1.6vw, 1.125rem);
  line-height: 1.25;
  color: var(--fg);
  opacity: 0.55;
  text-align: center;
  letter-spacing: 0.01em;
  padding: 0 0.5rem;
}

/* Disabled "Soon" button in the card's meta row. Visually muted and
   non-interactive to read as "not-yet-purchasable". Reuses .add-btn so
   the size/padding matches the active button on adjacent spell cards. */
.add-btn-disabled,
.add-btn[disabled] {
  background: transparent;
  color: var(--muted);
  border-color: rgba(255, 255, 255, 0.14);
  cursor: not-allowed;
  opacity: 0.65;
}
.add-btn-disabled:hover,
.add-btn[disabled]:hover {
  background: transparent;
  color: var(--muted);
  border-color: rgba(255, 255, 255, 0.14);
}

/* "TBD" price — muted since it's not a real price. */
.spell-card-kit .spell-price {
  color: var(--muted);
  letter-spacing: 0.08em;
  font-size: 0.8rem;
}

/* ============================================================
   "Creative, à la carte" subsection on the Craft page — a new
   editorial layer introducing the tiers. Cursive headline in the
   craft-section gold, followed by a descriptor paragraph, then
   the tracked-caps "PICK YOUR POISON" label sets up the tier list.
   ============================================================ */
.tiers-headline {
  font-family: 'Limoncello Recipe', cursive;
  font-weight: 400;
  font-size: clamp(1.75rem, 3vw, 2.5rem);
  line-height: 1.15;
  color: var(--craft);
  margin: 0 0 1rem;
}
.tiers-descriptor {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--fg);
  font-weight: 300;
  max-width: 48rem;
  margin: 0 0 2rem;
}
@media (max-width: 640px) {
  .tiers-descriptor { font-size: 1rem; }
}

/* ============================================================
   Cauldron illustration and "Pick your poison" menu card on the
   Craft page. The cauldron is a decorative section break. The menu
   below is a hairline-bordered card styled like a tavern menu,
   with a tracked-caps title, a small sparkle divider, tier rows,
   and a closing crescent moon.
   ============================================================ */

.tiers-illustration {
  display: flex;
  justify-content: center;
  margin: 2.5rem 0 0.5rem;
}
.tiers-illustration img {
  width: 100%;
  max-width: 14rem;
  height: auto;
  display: block;
}

.tiers-menu {
  margin: 2.5rem 0 0;
  padding: 2.5rem 3rem 2rem;
  border: 1px solid rgba(232, 176, 74, 0.4);
  background: rgba(232, 176, 74, 0.02);
}

.tiers-menu-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-bottom: 0.5rem;
}

.tiers-menu-label {
  color: var(--craft);
  font-size: 0.8rem;
  letter-spacing: 0.32em;
  margin-bottom: 0.5rem;
}

/* Decorative rule with a centered sparkle mark — breaks the header
   off from the tier rows like a menu's title-under-rule. */
.tiers-menu-rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  width: 60%;
  max-width: 18rem;
  margin: 1.5rem auto 0.5rem;
  color: rgba(232, 176, 74, 0.55);
}
.tiers-menu-rule::before,
.tiers-menu-rule::after {
  content: '';
  flex: 1;
  height: 1px;
  background: currentColor;
}
.tiers-menu-rule-mark {
  font-size: 0.85rem;
  line-height: 1;
  color: var(--craft);
}

@media (max-width: 640px) {
  .tiers-illustration img {
    max-width: 11rem;
  }
  .tiers-menu {
    padding: 2rem 1.5rem 1.5rem;
  }
  .tier {
    grid-template-columns: 4.5rem 1fr;
    gap: 1.25rem;
    padding: 1.5rem 0;
  }
  .tier-icon img {
    max-width: 3.5rem;
  }
  .tier-name {
    font-size: 1.125rem;
  }
}

/* ============================================================
   Two-column footer on the Spells page: the "suggest a spell" form
   pairs with the "Coven in the wild" vending-machine feature. On
   wide screens they sit side-by-side as equal-width columns with
   a vertical hairline between them; on narrower screens they stack
   back to a single column with the default internal layouts.
   ============================================================ */

.spells-footer-grid {
  margin-top: 5rem;
  padding-top: 3rem;
  border-top: 1px solid rgba(142, 169, 212, 0.18);
}

@media (min-width: 1100px) {
  .spells-footer-grid {
    display: grid;
    /* 50/50 split now that the vending-machine copy is tighter. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 4rem;
    align-items: start;
    position: relative;
  }
  .spells-footer-grid::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    /* Divider sits at the 50% split, inside the 4rem gap. */
    left: 50%;
    width: 1px;
    background: rgba(142, 169, 212, 0.18);
    transform: translateX(-50%);
    pointer-events: none;
  }

  /* Inside the grid, drop the children's own top separators since the
     parent now owns the horizontal rule. Also drop the form's max-width
     cap so it can fill its column. */
  .spells-footer-grid .suggest-spell,
  .spells-footer-grid .coven-around-town {
    margin: 0;
    padding-top: 0;
    border-top: 0;
    max-width: 100%;
  }

  /* The vending machine's internal image|copy columns: title sits flush
     at the top of the copy column to align with "What spell should we
     make next?" in the adjacent column. The image fills its column at
     natural aspect ratio; since the image is taller than the copy block
     it will extend slightly below the last address, which is acceptable
     given the visual weight it provides. */
  .spells-footer-grid .coven-around-town {
    align-items: start;
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    gap: 2rem;
  }
  .spells-footer-grid .coven-around-town-image {
    margin: 0;
    transform: translateY(-1.125rem);
  }
  .spells-footer-grid .coven-around-town-image img {
    display: block;
    width: 100%;
    height: auto;
  }
}

/* ============================================================
   The Shop page — subsection structure
   ----------------------------------------------------------------
   The shop has two top-level subsections: Spells (with its own
   nested "Spell sets" list) and Brand magic. Each gets a title
   treatment that's a step below the page H2 ("The shop") but
   clearly more prominent than the tracked-caps labels used for
   row dividers elsewhere on the site.
   ============================================================ */

.shop-subsection {
  margin-top: 3rem;
}
.shop-subsection:first-child {
  margin-top: 2rem;
}

/* Top-level subsection title — matches the page H2 cursive treatment
   used on other pages ("The craft", "The lore") so the shop's subsections
   read as proper page-level headings. Uses Limoncello Recipe cursive at
   a large scale. */
.shop-subsection-title {
  font-family: 'Limoncello Recipe', cursive;
  font-weight: 400;
  font-style: normal;
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  line-height: 1;
  letter-spacing: 0;
  color: var(--offering);
  margin: 0 0 1.5rem;
}

/* "Spell sets" is a sub-subsection inside Spells, so it sits at
   a lower tier than the top "Spells" title. Smaller cursive, with a
   hairline above to divide it from the expanded spells grid. */
.shop-subsection-title-sets {
  font-size: clamp(1.35rem, 2.5vw, 1.75rem);
  margin-top: 4rem;
  padding-top: 2.5rem;
  border-top: 1px solid rgba(142, 169, 212, 0.18);
}

/* Brand magic sits well below the Coven-in-the-wild footer grid,
   so add a generous separator to divide it from the prior content. */
.shop-subsection-brand {
  margin-top: 6rem;
  padding-top: 3rem;
  border-top: 1px solid rgba(142, 169, 212, 0.18);
}

/* On the Shop page, subsection titles inherit the section's pale-indigo
   offering accent. The Spells page uses its own color rule for these. */
.section-offering .shop-subsection-title {
  color: var(--offering);
}

/* Placeholder copy inside each empty Shop subsection. Small, muted,
   sits just under the cursive title while the section is unbuilt. */
.shop-subsection-placeholder {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 1rem;
  font-weight: 300;
  color: var(--muted);
  margin: 0.75rem 0 0;
  letter-spacing: 0.02em;
}

/* Quiet aside that sits below a populated subsection grid. Used to
   hand-off scope we don't carry (e.g. pointing visitors to another
   shop for adjacent goods). Italic, muted, low-key on purpose. */
.shop-subsection-callout {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.9375rem;
  font-weight: 300;
  font-style: italic;
  line-height: 1.6;
  color: var(--muted);
  margin: 2rem 0 0;
  max-width: 48rem;
}
.shop-subsection-callout a {
  color: var(--fg);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color 0.2s ease;
}
.shop-subsection-callout a:hover {
  color: var(--accent);
}

/* ============================================================
   Shop product cards
   ----------------------------------------------------------------
   Pattern for physical-object products in each Shop subsection
   (Swag, Spellcasting, Objects, Books). Distinct from spell cards —
   product photography is full-color/warm-lit, so these tiles don't
   use the spell cards' red/black aesthetic. Instead: clean frame,
   photo, title block, footer with price + Add button.
   ============================================================ */
.shop-product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 2rem;
  margin-top: 2rem;
}
.shop-product {
  display: flex;
  flex-direction: column;
  background: #141414;
  border: 1px solid rgba(142, 169, 212, 0.15);
  transition: border-color 160ms ease, transform 160ms ease;
}
.shop-product:hover,
.shop-product:focus-within {
  border-color: rgba(142, 169, 212, 0.4);
}
.shop-product-cover {
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: #0c0c0c;
}
.shop-product-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Flippable product cover — two images stacked. Front is visible by
   default; on hover (desktop), focus (keyboard), or .is-flipped (tap
   on touch) the back fades in above it. */
.shop-product-cover-flip {
  position: relative;
}
/* Smoke crossfade — same visual language as the kit reveal (blur +
   opacity, staggered so the two faces don't overlap muddily) but
   tightened for a tee flip, which is a hover/tap interaction rather
   than a slow cinematic reveal. Front clears first, back settles in
   right behind it. */
.shop-product-cover-flip .shop-product-img {
  position: absolute;
  inset: 0;
}
.shop-product-cover-flip .shop-product-img-front {
  opacity: 1;
  filter: blur(0);
  transition: filter 380ms ease-in, opacity 380ms ease-in;
}
.shop-product-cover-flip .shop-product-img-back {
  opacity: 0;
  filter: blur(12px);
  transition: filter 520ms ease-out 200ms,
              opacity 520ms ease-out 200ms;
}
.shop-product-flippable:hover .shop-product-cover-flip .shop-product-img-front,
.shop-product-flippable:focus-within .shop-product-cover-flip .shop-product-img-front,
.shop-product-flippable.is-flipped .shop-product-cover-flip .shop-product-img-front {
  opacity: 0;
  filter: blur(12px);
}
.shop-product-flippable:hover .shop-product-cover-flip .shop-product-img-back,
.shop-product-flippable:focus-within .shop-product-cover-flip .shop-product-img-back,
.shop-product-flippable.is-flipped .shop-product-cover-flip .shop-product-img-back {
  opacity: 1;
  filter: blur(0);
}
.shop-product-body {
  padding: 1.25rem 1.25rem 0.75rem;
  flex: 1 1 auto;
}
.shop-product-title {
  font-family: 'Archivo', sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0;
  color: var(--fg);
  letter-spacing: -0.01em;
}
.shop-product-tagline {
  font-family: 'Limoncello Recipe', cursive;
  font-size: 1.1rem;
  color: var(--offering);
  margin: 0.1rem 0 0.8rem;
}
.shop-product-desc {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.95rem;
  font-weight: 300;
  line-height: 1.5;
  color: var(--fg);
  margin: 0;
}
.shop-product-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.25rem 1.25rem;
  gap: 1rem;
}
.shop-product-price {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 1.1rem;
  font-weight: 400;
  color: var(--fg);
  letter-spacing: 0.02em;
}

/* ============================================================
   Expand-to-see-more CTA
   ----------------------------------------------------------------
   A centered text-link style button below the visible spells grid,
   matching the site's teaser-link vocabulary (1.5px underline, arrow
   that slides on hover). Clicking reveals the rest of the spells
   and removes this button.
   ============================================================ */

.spell-grid-expand {
  display: block;
  margin: 2rem auto 0;
  padding: 0.5rem 0;
  background: none;
  border: 0;
  font-family: 'Libre Franklin', sans-serif;
  font-size: 1rem;
  font-weight: 400;
  color: var(--offering);
  cursor: pointer;
  border-bottom: 1.5px solid rgba(142, 169, 212, 0.7);
  padding-bottom: 0.15rem;
  transition: color 180ms ease, border-color 180ms ease;
}
.spell-grid-expand:hover {
  color: #fff;
  border-bottom-color: var(--offering);
}
.spell-grid-expand .teaser-arrow {
  display: inline-block;
  margin-left: 0.2em;
  transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.spell-grid-expand:hover .teaser-arrow {
  transform: translateX(4px);
}

/* The hidden grid sits below the expand button. When it becomes visible
   via JS, collapse the gap above so it joins the visible grid naturally
   as a continuation rather than a separate block. */
.spell-grid-hidden {
  margin-top: 1rem;
}

/* Ensure the HTML [hidden] attribute actually hides elements even when
   class rules later set display: grid / flex / etc. */
[hidden] {
  display: none !important;
}

/* ============================================================
   Kit card reveals — Smoke
   ----------------------------------------------------------------
   Kit / spell-set cards reveal their back face on hover (desktop)
   or tap (mobile, .is-revealed class added by JS pointerup
   handler). The front face blurs out and fades; the back face
   then emerges from blur to clear. Staggered timing so the two
   don't overlap muddily in the middle.

   Structure expected:
     .kit-reveal-card
       .kit-reveal-front  (default face)
       .kit-reveal-back   (revealed via smoke crossfade)
   ============================================================ */

.kit-reveal-card {
  position: relative;
  display: block;
  cursor: pointer;
  outline: none;
}
.kit-reveal-card:focus-visible {
  outline: 2px solid var(--offering);
  outline-offset: 2px;
}

.kit-reveal-front {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  z-index: 1;
  /* Front exits first: relatively quick fade + blur, no delay. */
  filter: blur(0);
  opacity: 1;
  transition: filter 700ms ease-in, opacity 700ms ease-in;
}

.kit-reveal-back {
  position: absolute;
  inset: 0;
  background: #0c0c0c;
  overflow: hidden;
  z-index: 2;
  /* Back enters after a delay so the front has time to clear first.
     Slower ease-out gives the back a settling-in quality. */
  filter: blur(14px);
  opacity: 0;
  transition: filter 1000ms ease-out 400ms,
              opacity 1000ms ease-out 400ms;
}

.kit-reveal-card:hover .kit-reveal-front,
.kit-reveal-card.is-revealed .kit-reveal-front {
  filter: blur(14px);
  opacity: 0;
}
.kit-reveal-card:hover .kit-reveal-back,
.kit-reveal-card.is-revealed .kit-reveal-back {
  filter: blur(0);
  opacity: 1;
}

/* Shared back-face content styling. */
.kit-reveal-back-inner {
  padding: 1.5rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  height: 100%;
}

.kit-card-back-title {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 500;
  font-size: 1.0625rem;
  line-height: 1.2;
  color: var(--offering);
  margin: 0 0 0.25rem;
}

/* Tagline — the one-line cursive hook for each kit. Limoncello Recipe
   matches the section titles' display treatment and gives the back
   face immediate character. */
.kit-card-back-tagline {
  font-family: 'Limoncello Recipe', cursive;
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1.2;
  color: var(--offering);
  margin: 0 0 0.5rem;
}

/* "Includes" caps label — small, tracked, sets off the physical contents
   list that follows. Uses the same .offerings-label treatment seen
   elsewhere on the page. */
.kit-card-back-label {
  font-family: 'Archivo', sans-serif;
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--offering);
  opacity: 0.75;
  margin: 0.5rem 0 0.4rem;
  display: block;
}

.kit-card-back-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.3rem 0.75rem;
}
.kit-card-back-list li {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.75rem;
  line-height: 1.35;
  color: var(--fg);
  font-weight: 300;
  opacity: 0.82;
  padding-left: 0.75rem;
  position: relative;
}
.kit-card-back-list li::before {
  content: '·';
  position: absolute;
  left: 0.2rem;
  top: -0.1em;
  color: var(--offering);
  font-size: 1rem;
  font-weight: 700;
}

/* "For the person who..." persona footer. Sits at the bottom of the
   back face, separated by a hairline — a small editorial endnote. */
.kit-card-back-persona {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.75rem;
  font-style: italic;
  font-weight: 300;
  line-height: 1.4;
  color: var(--muted);
  margin: auto 0 0;
  padding-top: 0.65rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Prose description — used for Commission (which has no items list)
   and for the Spellbook bundle's back face. */
.kit-card-back-desc {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.8125rem;
  font-weight: 300;
  line-height: 1.5;
  color: var(--fg);
  opacity: 0.82;
  margin: 0;
}

/* ============================================================
   The Spells page (/spells/) uses the gold --spells accent
   instead of the blue --offering accent that its content
   originally inherited from the Shop page. Scope an override
   so every --offering reference inside .section-spells
   resolves to the gold spells color.

   Hairline separators that hard-code the blue are overridden
   to gold below.
   ============================================================ */

.section-spells {
  --offering: var(--spells);
}

/* Section title / number color (used by homepage spells teaser). */
.section-spells .section-title,
.section-spells .section-number { color: var(--spells); }

/* Teaser link color for the homepage spells teaser. */
.section-spells .teaser-link {
  color: var(--spells);
  border-bottom-color: rgba(232, 176, 74, 0.7);
}
.section-spells .teaser-link:hover {
  border-bottom-color: var(--spells);
}

/* Subsection title color — uses the CSS var so it picks up gold. */
.section-spells .shop-subsection-title {
  color: var(--spells);
}

/* Hairline separators that previously hard-coded the blue. */
.section-spells .shop-subsection-title-sets,
.section-spells .shop-subsection-brand,
.section-spells .spells-footer-grid {
  border-color: rgba(232, 176, 74, 0.3);
}
.section-spells .spells-footer-grid::before {
  background: rgba(232, 176, 74, 0.3);
}
.section-spells .coven-around-town {
  border-color: rgba(232, 176, 74, 0.3);
}
.section-spells .suggest-spell {
  border-color: rgba(232, 176, 74, 0.3);
}

/* Suggest-a-spell submit button — outlined gold at rest to match the
   Add button treatment used everywhere else on the site (yellow text,
   softened outline, fills solid on hover). Previously this button
   was filled-at-rest, which made it the loudest element on the bottom
   of the spells page. Now it sits in line with the rest of the
   commerce affordances. */
.section-spells .suggest-spell-submit {
  background: transparent;
  color: var(--spells);
  border: 1px solid rgba(232, 176, 74, 0.68);
}
.section-spells .suggest-spell-submit:hover {
  background: var(--spells);
  color: var(--bg);
  border-color: var(--spells);
}

/* Coven in the wild label + title in gold. */
.section-spells .coven-around-town .offerings-label,
.section-spells .coven-around-town-title,
.section-spells .suggest-spell-title {
  color: var(--spells);
}

/* Expand CTA in gold. */
.section-spells .spell-grid-expand {
  color: var(--spells);
  border-bottom-color: rgba(232, 176, 74, 0.7);
}
.section-spells .spell-grid-expand:hover {
  color: #fff;
  border-bottom-color: var(--spells);
}

/* ============================================================
   Homepage "The craft" section recolor — red instead of gold
   ----------------------------------------------------------------
   The homepage's #craft section was inheriting the gold --craft
   color. Since gold is now reserved for The Spells page, this
   section gets its own red accent to match the coven wordmark.
   Scoped to #craft on the homepage via the ID selector so only
   that one section is affected.
   ============================================================ */

#craft.section-craft {
  --craft: var(--accent);  /* remaps craft -> red, but only in this section */
}

/* Hardcoded gold values used by section-craft styles need explicit overrides
   so those also shift to red within this scope. */
#craft.section-craft .section-placeholder,
#craft.section-craft .section-offerings {
  border-color: rgba(200, 50, 45, 0.25);
  color: var(--accent);
}

/* Section-body disclaimer was craft-colored; make it red to match. */
#craft.section-craft .section-disclaimer {
  color: var(--accent);
}

/* Teaser link underline color tied to accent. */
#craft.section-craft .teaser-link-craft {
  color: var(--accent);
  border-bottom-color: rgba(200, 50, 45, 0.7);
}
#craft.section-craft .teaser-link-craft:hover {
  border-bottom-color: var(--accent);
}

/* ============================================================
   Homepage Shop teaser section — styled with the blue --offering
   accent (now reserved for the Shop family). Sits between the
   Spells and Lore teasers.
   ============================================================ */

.section-shop-teaser .section-title {
  color: var(--offering);
}

.section-shop-teaser .teaser-link-shop {
  color: var(--offering);
  border-bottom-color: rgba(142, 169, 212, 0.7);
}
.section-shop-teaser .teaser-link-shop:hover {
  border-bottom-color: var(--offering);
}

/* ============================================================
   Spell kits hero banner — full-width image above the kit grid.
   Sits between the H4 heading and the cards. Editorial feel:
   line shot of the kit boxes as a category preview.
   ============================================================ */
.spell-kits-hero {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 0 2.5rem 0;
  border-radius: 4px;
  object-fit: cover;
}
@media (max-width: 700px) {
  .spell-kits-hero {
    margin-bottom: 1.5rem;
    border-radius: 2px;
  }
}

/* ============================================================
   Kit cards with real product photography (vs. FPO typographic
   placeholder). The .cover-kit-photo modifier suppresses the
   typographic styling and makes the image fill the cover slot.
   ============================================================ */
.cover-kit.cover-kit-photo {
  padding: 0;
  background: transparent;
  display: block;
  position: relative;
  overflow: hidden;
}
.cover-kit.cover-kit-photo .spell-cover-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ============================================================
   Spell collaborations — collab cards use .spell-card-kit chrome
   but should NOT inherit the kit row's span:2 / span-full mobile
   behavior. Override to keep collabs flowing as natural grid cells
   so they show 4-per-row on desktop and 2-per-row on mobile.
   ============================================================ */
.spell-collabs-grid .spell-card-kit {
  grid-column: auto;
}

/* ============================================================
   Spell kits row — each kit card spans 2 grid columns.
   Base spell grid is 4 columns; kits at span 2 = 2 per row, so
   8 kits fills cleanly into 4 rows with no orphaned tile. Mobile
   breakpoints fall back gracefully as the parent grid collapses:
   at 3 cols → kits span 3 (1 per row, full-width);
   at 2 cols → kits span 2 (1 per row, full-width);
   at 1 col  → kits span 1 (1 per row, already full-width).
   ============================================================ */
.spell-sets-grid .spell-card-kit {
  grid-column: span 2;
}
@media (max-width: 1100px) {
  .spell-sets-grid .spell-card-kit {
    grid-column: 1 / -1;
  }
}

/* ============================================================
   Spells page hero shot — product photo of cards spread around
   the Spellbook, sits between the section description and the
   first grid of spell cards. Full content width, rounded edges
   that match the card tiles, and breathing room above & below.
   ============================================================ */
.spells-hero {
  margin: 1.5rem 0 2rem;
  padding: 0;
}
.spells-hero img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0.375rem;
  border: 1px solid rgba(168, 125, 196, 0.18);
}

/* ============================================================
   Spells page theme filter — row of pills between the hero
   image and the spell grid. Pills are subtle by default; the
   active one gets the gold spells color. Horizontal scroll on
   narrow screens so the pills don't cram/wrap awkwardly.
   ============================================================ */
.spell-filter {
  margin: 0.5rem 0 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.spell-filter-label {
  font-family: 'Archivo', sans-serif;
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.spell-filter-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.spell-filter-pill {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid rgba(168, 125, 196, 0.3);
  color: var(--fg);
  font-family: 'Archivo', sans-serif;
  font-weight: 500;
  font-size: 0.875rem;
  letter-spacing: 0.04em;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}
.spell-filter-pill:hover {
  border-color: var(--spells);
  color: var(--spells);
}
.spell-filter-pill.is-active {
  background: var(--spells);
  border-color: var(--spells);
  color: var(--bg);
}

@media (max-width: 640px) {
  .spell-filter-pills {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 0.25rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .spell-filter-pills::-webkit-scrollbar { display: none; }
  .spell-filter-pill { flex-shrink: 0; }
}

/* When a non-"All" filter is active, the expand CTA and the
   hidden grid's "hidden" state are overridden via a class
   added to the section by JS. */
.spell-filter-active .spell-grid-expand {
  display: none;
}

/* When a filter is active, hide the "visible first 8" grid and the
   "visible first 4 kits" grid — their matching cards are moved into
   the hidden grids (which are revealed) so results flow continuously.
   When the filter is cleared, cards are moved back. */
.spell-filter-active .spell-grid-visible,
.spell-filter-active .spell-sets-grid-visible {
  display: none;
}

/* Each spell card gets a data-themes attr listing its themes.
   JS toggles a .spell-card-filtered-out class when a filter is
   active and this card doesn't match. */
.spell-card-filtered-out {
  display: none !important;
}

/* ============================================================
   Keep in touch — newsletter signup block at the bottom of the
   Lore page. Sits as a quiet outro after the client logos.
   Inherits the lore section's gold accent via var(--offering).
   ============================================================ */
.keep-in-touch {
  margin-top: 4rem;
  padding-top: 3rem;
  border-top: 1px solid var(--hairline);
}
/* When the block sits inside the contact page and already carries the
   .contact-block class, its surrounding rhythm (padding + border-top)
   comes from .contact-block — don't double up. */
.contact-block.keep-in-touch {
  margin-top: 0;
  padding-top: 2.5rem;
  border-top: 1px solid rgba(167, 125, 196, 0.18);
}
/* Homepage version — the enclosing <section class="section section-contact">
   already provides top padding and the section-title above it supplies
   visual weight, so strip the block-level top margin/padding/border. */
.keep-in-touch-home {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.keep-in-touch-title {
  margin: 0 0 1rem;
  color: var(--contact);
}
.keep-in-touch-lede,
.keep-in-touch-form {
  max-width: 38rem;
}
.keep-in-touch-lede {
  margin: 0 0 1.5rem;
}
.keep-in-touch-form {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
  flex-wrap: wrap;
}
.keep-in-touch-input {
  flex: 1 1 18rem;
  background: transparent;
  border: 1px solid rgba(168, 125, 196, 0.3);
  color: var(--fg);
  font-family: 'Archivo', sans-serif;
  font-size: 1rem;
  padding: 0.75rem 1rem;
  border-radius: 0;
  outline: none;
  transition: border-color 0.15s ease;
}
.keep-in-touch-input::placeholder {
  color: var(--muted);
  opacity: 0.7;
}
.keep-in-touch-input:focus {
  border-color: var(--contact);
}
.keep-in-touch-submit {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid var(--contact);
  color: var(--contact);
  font-family: 'Archivo', sans-serif;
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.75rem 1.5rem;
  border-radius: 0;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}
.keep-in-touch-submit:hover {
  background: var(--contact);
  color: var(--bg);
}
.keep-in-touch-fine-print {
  margin: 0.75rem 0 0;
  font-family: 'Archivo', sans-serif;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.keep-in-touch-thanks {
  margin: 1rem 0 0;
  font-family: 'Archivo', sans-serif;
  font-size: 1rem;
  color: var(--contact);
}

/* Visually-hidden label for screen readers. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Homepage echo of the newsletter signup — quieter than the teaser
   sections above it. One-line paragraph with an inline link to the
   real form on the Lore page. Sits as a small coda before the footer. */
.section-keep-in-touch {
  padding-top: 4rem;
  padding-bottom: 8rem;
}
.keep-in-touch-echo {
  font-family: 'Archivo', sans-serif;
  font-size: 1rem;
  color: var(--muted);
  margin: 0;
}
.keep-in-touch-echo .teaser-link {
  margin-left: 0.5rem;
}

/* ============================================================
   NAV TOTE / CART ICON
   Tote-shaped icon in the top-right of the nav, after "Make contact".
   Replaces (visually) the supermarket cart energy with a boutique tote.
   ============================================================ */
.nav-cart-item {
  display: flex;
  align-items: center;
}
.nav-cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  transition: color 0.15s ease, transform 0.15s ease;
}
.nav-cart-link:hover {
  color: #fff;
  transform: translateY(-1px);
}
.nav-cart-icon {
  display: block;
}
.nav-cart-count {
  position: absolute;
  top: -2px;
  right: -4px;
  background: #c4302b;
  color: #fff;
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.625rem;
  font-weight: 500;
  min-width: 1rem;
  height: 1rem;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.25rem;
  line-height: 1;
}
.nav-cart-count[hidden] {
  display: none;
}
@media (max-width: 720px) {
  .nav-cart-link {
    width: 1.75rem;
    height: 1.75rem;
  }
  .nav-cart-icon {
    width: 18px;
    height: 18px;
  }
}

/* ============================================================
   HOMEPAGE QUICK-FILTER PILLS
   Sit under the "See all the spells" CTA on the homepage. Each links
   to /spells/#filter=<theme>; the spells page reads the hash on
   load and activates the matching filter.
   ============================================================ */
.teaser-pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 0.5rem;
  margin-top: 1.5rem;
}
.teaser-pill {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: 0.5px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.7);
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.teaser-pill:hover {
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.3);
}
@media (max-width: 720px) {
  .teaser-pills {
    gap: 0.4rem;
    margin-top: 1.25rem;
  }
  .teaser-pill {
    padding: 0.4rem 0.85rem;
    font-size: 0.65rem;
  }
}

/* ============================================================
   "START HERE" SPOTLIGHT
   Editorial single-product card. Image left, copy right on desktop.
   Stacks on mobile. Sits between the spells teaser and kits row.
   ============================================================ */
.section-start-here {
  padding-top: 4rem;
  padding-bottom: 4rem;
}
.start-here-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
  align-items: center;
  max-width: 64rem;
  margin: 0 auto;
}
.start-here-image img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}
.start-here-body {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.start-here-eyebrow {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--craft, #d4a373);
}
.start-here-title {
  font-family: 'Apex Mk2 Black', sans-serif;
  font-size: 2.25rem;
  font-weight: 900;
  line-height: 1;
  margin: 0;
  color: #fff;
  text-transform: lowercase;
  letter-spacing: -0.02em;
}
.start-here-tagline {
  font-family: 'Limoncello Recipe', cursive;
  font-size: 1.5rem;
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
}
.start-here-desc {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.95rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.75);
  margin: 0;
}
.teaser-link-start-here {
  margin-top: 0.5rem;
  align-self: flex-start;
}
@media (max-width: 720px) {
  .section-start-here {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }
  .start-here-card {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  .start-here-title {
    font-size: 1.75rem;
  }
  .start-here-tagline {
    font-size: 1.25rem;
  }
  .start-here-desc {
    font-size: 0.875rem;
  }
}

/* ============================================================
   HOMEPAGE KITS TEASER GRID
   4 kit cards in a row on desktop, 2 on tablet, 1 on mobile.
   Reuses the existing .spell-card-kit / .cover-kit / .cover-kit-photo
   styles defined elsewhere; only the grid container is custom.
   ============================================================ */
.kits-grid-teaser {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  margin-top: 2rem;
}
@media (max-width: 1024px) {
  .kits-grid-teaser {
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
  }
}
/* Mobile kit thumbnails: tighter horizontal crop on the photo so the
   kit boxes feel more vertical and substantial at small sizes. The
   wide kit photos (which read fine at desktop) start to feel hemmed-in
   on a phone where the kit itself is centered with a lot of empty
   concrete background on either side. We crop ~12% off each horizontal
   edge so the kit takes up more of the visible thumbnail. The CSS
   `object-fit: cover` paired with a slightly taller aspect-ratio
   ensures the kit stays centered and never gets clipped. This applies
   only to .kits-grid-teaser (homepage 2x2 kit thumbs) — the
   Spellcasting Starter Kit hero feature below uses a different class
   and keeps its full-width photo. */
@media (max-width: 600px) {
  .kits-grid-teaser .cover-kit-photo {
    aspect-ratio: 4 / 5;
  }
  .kits-grid-teaser .cover-kit-photo .spell-cover-image {
    object-fit: cover;
    object-position: center center;
    width: 100%;
    height: 100%;
  }
}
/* Override the spells-page grid-column: span 2 rule that kit cards
   inherit by default — on the homepage teaser, each card is a single
   grid cell. */
.kits-grid-teaser .spell-card-kit {
  grid-column: auto;
}

/* ============================================================
   BOTTOM 2-UP: SUGGEST + PRESS
   Two columns side-by-side on desktop; stacked on mobile. Sits below
   the kits teaser and above "Join the coven".
   ============================================================ */
.section-suggest-press {
  padding-top: 1.5rem;
  padding-bottom: 4rem;
}

/* The suggest-press grid mirrors the .spells-footer-grid pattern:
   - Horizontal hairline above (border-top) + 3rem padding-top
   - Vertical separator at 50% via ::before (only on wide screens
     where the columns sit side by side)
   On narrow screens, the grid stacks and only the horizontal hairline
   remains. */
.suggest-press-grid {
  /* Span the full section content width: Press hugs the left content
     edge (matching "Drop your email" above), the right column extends
     toward the right edge, and the vertical hairline at 50% of the
     grid lands exactly at page-center.
     Previously `margin: 0 auto; max-width: 64rem` centered a narrower
     grid — both columns sat around mid-page and the perpendicular
     hairline was centered. Then dropping `margin: 0 auto` left-aligned
     the narrow grid which pulled the right column left too. Removing
     the max-width restores the right column's horizontal position
     while keeping the left column flush. */
  padding-top: 3rem;
}

@media (min-width: 1100px) {
  .suggest-press-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 4rem;
    align-items: start;
    position: relative;
  }
  .suggest-press-grid::before {
    content: '';
    position: absolute;
    /* Extend the vertical hairline up through the parent section's
       padding-top so it meets the horizontal section-top hairline.
       Value matches .section-suggest-press { padding-top }; if that
       changes, this must change too. */
    top: -1.5rem;
    bottom: 0;
    /* Divider sits at the 50% split, inside the 4rem gap. */
    left: 50%;
    width: 1px;
    background: rgba(142, 169, 212, 0.18);
    transform: translateX(-50%);
    pointer-events: none;
  }
  /* When the columns are side by side, the children's titles need to
     start flush at the top so they vertically align. The spells-footer
     drops top margins on its children for the same reason. */
  .suggest-press-grid .suggest-spell,
  .suggest-press-grid .press {
    margin-top: 0;
    padding-top: 0;
  }
  .suggest-press-grid .suggest-spell-title,
  .suggest-press-grid .press-title {
    margin-top: 0;
  }
}

/* Stacked layout (below 1100px): Press sits on top, suggest below.
   Without a separator, the two sections collapse together visually —
   the TBD slots butt right up against the cursive "What spells should
   we make next?" title. Add a horizontal hairline + breathing room
   above the suggest block to mirror the visual weight of the vertical
   divider that exists at desktop widths. */
@media (max-width: 1099px) {
  .suggest-press-grid .suggest-spell {
    margin-top: 2.5rem;
    padding-top: 2.5rem;
    border-top: 1px solid rgba(142, 169, 212, 0.18);
  }
}

/* PRESS BLOCK */
.press {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.press-title {
  font-family: 'Limoncello Recipe', cursive;
  font-size: 1.85rem;
  font-weight: 400;
  color: #fff;
  margin: 0;
  line-height: 1;
}
.press-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}
.press-slot {
  aspect-ratio: 16 / 9;
  background: rgba(255, 255, 255, 0.03);
  border: 0.5px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
/* Press wordmark — typography-only "logos" since we're using
   placeholder placements for now. Each gets its own treatment that
   approximates the real publication's wordmark feel: serif for
   newspapers, sans for digital, etc. */
.press-wordmark {
  color: rgba(255, 255, 255, 0.55);
  text-align: center;
  line-height: 1.1;
  user-select: none;
}
.press-wordmark-sfchronicle {
  font-family: 'Libre Franklin', serif;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  font-variant: small-caps;
}
.press-wordmark-sfstandard {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.press-wordmark-domino {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 1.5rem;
  font-weight: 300;
  letter-spacing: 0.25em;
  text-transform: uppercase;
}
.press-wordmark-sisterdistrict {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
@media (max-width: 720px) {
  .section-suggest-press {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }
  /* On mobile the grid is just stacked block flow (the desktop
     min-width rule never fires), so children stack naturally and we
     only need to add a small gap between them via margin. */
  .suggest-press-grid .press {
    margin-bottom: 2.5rem;
  }
  .press-grid {
    gap: 0.5rem;
  }
  .press-wordmark-sfchronicle { font-size: 0.8rem; }
  .press-wordmark-sfstandard { font-size: 0.9rem; }
  .press-wordmark-domino { font-size: 1.1rem; letter-spacing: 0.2em; }
  .press-wordmark-sisterdistrict { font-size: 0.7rem; }
}

/* ============================================================
   SECTION SUBTITLE — tiered-down heading for sub-sections
   Used by "Spell kits" sub-heading inside the main spells teaser
   section, where the kits are a category within the spells universe
   rather than a top-level section of the page. Smaller than
   .section-title (which uses Limoncello cursive at large size).
   ============================================================ */
.section-subtitle {
  font-family: 'Limoncello Recipe', cursive;
  font-size: 2rem;
  font-weight: 400;
  color: var(--craft, #d4a373);
  margin: 4rem 0 1.5rem;
  line-height: 1;
  text-align: left;
}
@media (max-width: 720px) {
  .section-subtitle {
    font-size: 1.6rem;
    margin: 2.5rem 0 1.25rem;
  }
}

/* ============================================================
   SHOP TEASER PRODUCT GRID
   4-up shoppable row on the homepage. Reuses .shop-product card
   styles from the shop page; only the grid container is custom.
   ============================================================ */
.shop-grid-teaser {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  margin: 2rem 0 0;
}
@media (max-width: 1024px) {
  .shop-grid-teaser {
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
  }
}

/* ============================================================
   HOMEPAGE-ONLY SUGGEST TITLE OVERRIDE
   The spells page uses the shop's --offering blue for the suggest
   form's "What spells should we make next?" title. On the homepage
   it sits in a more neutral context next to the press section, so
   white reads cleaner and less category-coded.
   ============================================================ */
.suggest-spell-home .suggest-spell-title {
  color: #fff;
}

/* ============================================================
   START HERE CTA — yellow (craft) variant
   The "View the kit" link inside the Spellcasting Starter Kit
   spotlight uses the page's craft/gold color instead of the default
   offering blue, so it ties to the eyebrow above it ("START HERE")
   and reads as part of the same editorial unit.
   ============================================================ */
.teaser-link-start-here {
  color: var(--craft);
  border-bottom-color: rgba(232, 176, 74, 0.7);
}
.teaser-link-start-here:hover {
  color: #f3c878;
  border-bottom-color: var(--craft);
}

/* ============================================================
   COMMISSION KIT — INQUIRE TREATMENT
   The Custom Spell Commission has no fixed price, so its meta row
   shows "Inquire for pricing" in the price slot (smaller/muted, since
   it's a longer string than a $XX price) plus a normal-sized
   "Inquire" button that goes to the contact page. The button is a
   plain .add-btn — same yellow/craft color and size as every other
   buy button on the site, so commission feels like part of the
   normal commerce flow rather than a special-snowflake card.
   ============================================================ */
.spell-price-inquire {
  font-size: 0.7rem;
  color: var(--muted);
  font-weight: 400;
  letter-spacing: 0.04em;
}
.add-btn-inquire {
  text-decoration: none;
  display: inline-block;
}

/* ============================================================
   HOMEPAGE-ONLY SUGGEST FORM — WHITE TREATMENT
   The spells page version uses --offering blue; on the homepage the
   form sits next to the press section in a more neutral context, so
   we override the textarea border, focus state, and submit button
   to use white instead. Title was already overridden separately.
   ============================================================ */
.suggest-spell-home .suggest-spell-form textarea {
  border-color: rgba(255, 255, 255, 0.28);
}
.suggest-spell-home .suggest-spell-form textarea:focus {
  border-color: #fff;
  background: rgba(255, 255, 255, 0.04);
}
.suggest-spell-home .suggest-spell-submit {
  color: #fff;
  border-color: #fff;
}
.suggest-spell-home .suggest-spell-submit:hover {
  background: #fff;
  color: #0c0c0c;
}

/* ============================================================
   PRESS TBD PLACEHOLDER + LORE 8-UP GRID
   Each press slot can hold either a real logo (img/svg) or a
   typographic "TBD" placeholder. Until coverage lands, all slots
   show TBD — honest about not having claimed any placements.

   The lore page variant (.press-grid-lore) uses an 8-up layout
   instead of the homepage's 4-up — more presence/credibility
   weight on the page where deeper trust signals live.
   ============================================================ */
.press-tbd {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.3);
  user-select: none;
}

.press-grid-lore {
  grid-template-columns: repeat(4, 1fr);
  margin-top: 1.25rem;
}
@media (max-width: 900px) {
  .press-grid-lore {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ============================================================
   LEGAL DISCLAIMER STRIP
   Sits in its own band between page content and the footer,
   visible enough to be read without scrolling to the deepest part
   of the page. Small, italic, low-contrast — present without
   competing with the brand voice or the footer's contact info.
   ============================================================ */
.legal-strip {
  padding: 2.5rem 1.5rem 0.5rem;
}
.footer-disclaimer {
  margin: 0 auto;
  max-width: 42rem;
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.75rem;
  font-style: italic;
  font-weight: 300;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.45);
  text-align: center;
}
@media (max-width: 720px) {
  .legal-strip {
    padding: 1.5rem 1.25rem 0.5rem;
  }
  .footer-disclaimer {
    font-size: 0.7rem;
  }
}

/* ============================================================
   HOMEPAGE SUGGEST/PRESS — SUPPRESS DUPLICATE HAIRLINE (desktop only)
   At ≥1100px the .suggest-press-grid is a 2-column layout with its
   own vertical ::before divider between the columns. The inner
   .suggest-spell has a default border-top from its standalone use
   on the spells page footer, and that border was visually crossing
   the title at the homepage. Suppress it ONLY at desktop where the
   grid's divider is doing the separation work. Below 1100px the
   sections stack vertically and need the inner border to act as
   their separator. (See the @media max-width: 1099px rule above.)
   ============================================================ */
@media (min-width: 1100px) {
  .suggest-press-grid .suggest-spell-home {
    border-top: 0;
    padding-top: 0;
    margin-top: 0;
  }
}

/* ============================================================
   JOIN THE COVEN — MOBILE LAYOUT REFINEMENTS
   On mobile, the form's flex-wrap put the email input on one row
   and the Join button alone on the next row — but without gap
   between the wrap rows and with the button hugging-left at its
   natural narrow width, the layout looked broken (button floating
   loose in empty space below the input). Three small fixes:

   1. When wrapped (flex direction stays row-wrap), give the wrap
      lines breathing room via `row-gap`.
   2. Make the Join button full-width when it wraps below the input,
      so it visually anchors the form bottom edge.
   3. Pull the fine-print closer to the form so it reads as a tag
      under the input/button, not an orphan paragraph.

   Mobile-only — desktop side-by-side input+button layout is fine.
   ============================================================ */
@media (max-width: 600px) {
  .keep-in-touch-form {
    row-gap: 0.625rem;
  }
  .keep-in-touch-submit {
    /* Mobile: don't stretch the button to the input's full width.
       Sized so its right edge lands roughly at the end of
       "anytime." in the fine-print line below — visually matched
       to that text's width, not the input's. */
    width: auto;
    min-width: 15rem;
    align-self: flex-start;
  }
  .keep-in-touch-fine-print {
    margin-top: 0.875rem;
  }
}

/* ============================================================
   SPELL DETAIL PAGES (/spells/{slug}/)
   Per-product editorial pages. Hero is a 2-column layout (cover
   left, metadata right) that stacks on mobile. Below the hero is
   the "why this spell" prose block — no section header, the
   prose stands alone as editorial. Bottom: "you may also like"
   row of 3 related spells reusing the spell-card component.
   ============================================================ */

.section-spell-detail {
  /* Slightly tighter section padding on detail pages — the hero is
     already visually substantial, no need for the listing page's
     deep top space. */
  padding-top: 4rem;
}

.spell-breadcrumb {
  font-family: 'Archivo', sans-serif;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: 2.5rem;
}
.spell-breadcrumb a {
  color: var(--muted);
  text-decoration: none;
  transition: color 0.15s ease;
}
.spell-breadcrumb a:hover {
  color: var(--craft);
}

/* Hero: cover image + metadata column. Stacks on mobile. */
.spell-detail-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  margin-bottom: 4.5rem;
}
@media (min-width: 800px) {
  .spell-detail-hero {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 4rem;
    align-items: start;
  }
}

.spell-detail-cover {
  margin: 0;
}
.spell-detail-cover img {
  width: 100%;
  height: auto;
  display: block;
  /* Slight border so the image edge doesn't disappear into the bg */
  border: 1px solid rgba(255, 255, 255, 0.04);
}

.spell-detail-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.25rem;
  /* On desktop give the column a max width so the Add button isn't
     uncomfortably wide on a 1400px viewport. */
  max-width: 30rem;
}

.spell-detail-number {
  font-family: 'Archivo', sans-serif;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

.spell-detail-title {
  font-family: 'Limoncello Recipe', cursive;
  font-weight: 400;
  font-size: clamp(2.5rem, 5vw, 4rem);
  line-height: 1;
  letter-spacing: 0;
  color: var(--craft);
  margin: 0;
}

.spell-detail-tagline {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 300;
  font-style: italic;
  font-size: 1.125rem;
  line-height: 1.4;
  color: var(--fg);
  margin: 0;
  max-width: 26rem;
}

/* Detail page price uses the .spell-price class (so existing Shopify
   hydration patches it) plus a detail-specific class for sizing. */
.spell-detail-price {
  font-family: 'Archivo', sans-serif;
  font-size: 1.625rem;
  font-weight: 500;
  color: var(--fg);
  margin: 0;
}

/* Larger Add button for the detail page — the listing page's compact
   pill is too small as the primary CTA on a product page. */
.add-btn-detail {
  font-family: 'Archivo', sans-serif;
  font-weight: 600;
  font-size: 0.85rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: var(--craft);
  color: var(--bg);
  border: 1px solid var(--craft);
  padding: 1rem 2.5rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
  align-self: stretch;
  max-width: 16rem;
}
.add-btn-detail:hover {
  background: transparent;
  color: var(--craft);
}
.add-btn-detail.added {
  background: transparent;
  color: var(--craft);
  opacity: 0.8;
}

.spell-detail-included {
  margin-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-top: 1.25rem;
  width: 100%;
}
.spell-detail-included-label {
  display: block;
  font-family: 'Archivo', sans-serif;
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.5rem;
}
.spell-detail-included-list {
  font-family: 'Libre Franklin', sans-serif;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--fg);
  margin: 0;
}

/* "Why this spell" prose — sits inside the metadata column, below
   the tagline. No section header — the prose stands on its own
   between the headline cluster (number/title/tagline) above and the
   purchase cluster (price/Add/Included) below. */
.spell-detail-description {
  width: 100%;
}
.spell-detail-description p {
  font-family: 'Libre Franklin', sans-serif;
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--fg);
  margin: 0 0 1rem;
}
.spell-detail-description p:last-child {
  margin-bottom: 0;
}

/* Related row */
.spell-detail-related {
  margin-top: 5rem;
  padding-top: 3rem;
  border-top: 1px solid var(--hairline);
}
.spell-detail-related-title {
  font-family: 'Limoncello Recipe', cursive;
  font-weight: 400;
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  line-height: 1;
  color: var(--craft);
  margin: 0 0 2rem;
}
.spell-grid-related {
  /* Always three across, even on narrow viewports — at the smallest
     phone widths the cards become small but still legible since the
     cover artwork is the load-bearing visual. Tight gap on mobile,
     looser on desktop. */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
}
@media (min-width: 700px) {
  .spell-grid-related {
    gap: 2rem;
  }
}
/* Related cards' anchor wrapper — make the cover + meta clickable as
   a unit, leaving Add separate. */
.spell-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
}

/* ============================================================
   HOMEPAGE CRAFT-STILL FIGURE
   Cinematic letterbox still that sits below the "*Our words are
   our own—written by humans" disclaimer in The Craft section.
   Functions as a quiet visual answer to the philosophical copy
   above: here are the actual objects we make. The image's 3:1
   aspect makes it read as an atmospheric still rather than a
   product photo, which lets it close the philosophy section
   without breaking its reading-mode tone.

   Stretches wider than the prose's max-width so it acts as a
   visual pause between the philosophy block and the spells
   teaser below. Generous top margin (4rem) gives the disclaimer
   text room to land before the image arrives.
   ============================================================ */
.craft-still {
  margin: 1.5rem 0 0;
  padding: 0;
}
.craft-still img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
}
@media (max-width: 720px) {
  .craft-still {
    margin-top: 1.5rem;
  }
}

/* ============================================================
   FOOTER BRAND LOCKUP
   The lockup wraps the wordmark + tagline so they behave as a
   single unit. The lockup itself is inline-flex column so it
   shrinks to fit the widest child (the wordmark). Inside the
   lockup, both children are centered horizontally — which means
   the tagline ("San Francisco") sits centered under the wordmark
   ("coven") regardless of the wordmark's exact width.

   Because the lockup is a shrink-to-fit inline element, its
   parent's text-align controls where the lockup sits. Desktop:
   the brand column has its own alignment context. Mobile: the
   parent (.footer-brand) is left-aligned, so the whole lockup
   anchors left while preserving its internal centering.
   ============================================================ */
.footer-brand-lockup {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
}

/* ============================================================
   THE CRAFT — "Pick a spell" CTA
   This link sits at the bottom of the persuasive copy, pointing
   to /spells/. Colored red to match the craft section's identity
   (the "coven" wordmark and section title). The visual continuity
   is "red prose → red CTA" within The Craft, then the destination
   page brings its own gold identity.
   ============================================================ */
.teaser-link-craft-cta {
  color: var(--accent);
  border-bottom-color: rgba(200, 50, 45, 0.7);
  margin-top: 0.5rem;
}
.teaser-link-craft-cta:hover {
  color: #d8463f;
  border-bottom-color: var(--accent);
}
