/* ==========================================================================
   The Color Tree
   Direction A (deep plum), structure W1.
   Type: Fraunces for headings and quotes, Instrument Sans for everything else.
   ========================================================================== */

:root{
  --plum:        #25091a;   /* page ground */
  --plum-deep:   #1a0512;   /* header, tinted bands */
  --plum-panel:  #1c0614;   /* the tree's panel */
  --plum-well:   #170410;   /* image wells */
  --line:        #3f1330;   /* hairline */
  --line-soft:   rgba(255,255,255,.08);
  --ink:         #f3e6ee;   /* body text */
  --ink-soft:    #d8b8cb;   /* secondary */
  --ink-mute:    #c299b1;   /* tertiary */
  --ink-faint:   #a0708b;   /* labels */
  --accent:      #cf0053;
  --accent-lift: #e5195f;
  --accent-text: #ff9dc2;
  --accent-hot:  #ff3377;   /* the pointer is ON the button. One step above
                               --accent-lift, so a card that has already warmed
                               to --accent still has somewhere brighter to go —
                               that gap is the whole point of the second stage */
  --lit:         .34s;      /* how long a button takes to reach a lit state.
                               Rest is .2s, so they cool faster than they warm:
                               the warm-up is the part you watch */
  --card-face:   #2d1222;   /* the card's translucent fill, flattened solid */
  --accent-half: #632b41;   /* the accent at half saturation — a held state,
                               not an invitation to press again */
  --line-btn:    #933163;   /* every button's outline — one token, so
                               "brighten it" is one edit instead of eight */
  --btn-face:    #4a1e38;   /* every button's RESTING fill. Deliberately a step
                               brighter than --card-face (#2d1222), which is the
                               lightest ground any button sits on — a button has
                               to read as a raised object on the card as well as
                               on the page, and transparent never could. */
  --maxw:        1080px;
}

*,*::before,*::after{box-sizing:border-box}

/* An author `display:` beats the browser's [hidden] rule, which once left an
   invisible full-screen overlay swallowing every click. Guard our own
   hideable components explicitly rather than globally — a blanket
   [hidden]{display:none!important} also overrides Ecwid's storefront, which
   toggles hidden on its own elements. */
.lightbox[hidden],
.hint-sheet[hidden],
.cart-panel[hidden],
.cart-veil[hidden],
.tree-hint[hidden],
.drawer[hidden],
.opts[hidden],
.opt[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--plum);
  color:var(--ink);
  font-family:'Instrument Sans',system-ui,-apple-system,sans-serif;
  font-size:16px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto;display:block}
h1,h2,h3{font-family:'Fraunces',Georgia,serif;font-weight:600;letter-spacing:-.015em;margin:0}
a{color:inherit}
button{font:inherit}

:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:-9999px;background:var(--accent);color:#fff;padding:.7rem 1rem;z-index:200}
.skip:focus{left:.5rem;top:.5rem}

.wrap{max-width:var(--maxw);margin:0 auto;padding-left:1.5rem;padding-right:1.5rem}

/* ---------- staging strip ---------------------------------------------- */
.staging{
  margin:0;padding:.5rem 1rem;text-align:center;font-size:.8rem;
  background:#3d1226;color:#e0b7cd;border-bottom:1px solid var(--line);
}
.staging a{color:var(--accent-text)}

/* ---------- header ------------------------------------------------------ */
.bar{
  position:sticky;top:0;z-index:60;
  display:flex;align-items:center;gap:1.2rem;
  padding:.55rem 1.2rem;
  background:rgba(26,5,18,.94);
  backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);
}
.mark{font-family:'Fraunces',Georgia,serif;font-weight:600;font-size:1.02rem;
  text-decoration:none;white-space:nowrap}
.bar-nav{margin-left:auto;display:flex;gap:1.15rem;font-size:.88rem}
.bar-nav a{color:var(--ink-mute);text-decoration:none}
.bar-nav a:hover{color:#fff}
.menu-btn{display:none;margin-left:auto;background:var(--btn-face);border:1px solid var(--line-btn);
  color:var(--ink);font-size:.82rem;padding:.4rem .75rem;cursor:pointer;border-radius:2px}
.menu-btn:hover{border-color:var(--accent-text)}
.cart-btn{
  display:flex;align-items:center;gap:.4rem;white-space:nowrap;text-decoration:none;
  background:var(--accent);color:#fff;font:inherit;font-size:.84rem;font-weight:600;
  border:none;cursor:pointer;padding:.45rem .85rem;border-radius:2px;
}
.cart-btn{transition:background .2s ease}
.cart-btn:hover{background:var(--accent-hot);transition:background var(--lit) ease}
.cart-btn.bump{animation:bump .35s ease}
@keyframes bump{50%{transform:scale(1.12)}}

.drawer{position:sticky;top:47px;z-index:59;background:var(--plum-deep);
  border-bottom:1px solid var(--line)}
.drawer a{display:block;padding:.9rem 1.2rem;border-top:1px solid var(--line);
  color:#e4cddb;text-decoration:none;font-size:.98rem}
.drawer a:first-child{border-top:none}

/* ---------- section rhythm ---------------------------------------------- */
section{padding:3.4rem 0}
section > .wrap > h2{font-size:1.95rem;margin-bottom:1.5rem}
.eyebrow{font-size:.78rem;color:var(--ink-faint);margin:0 0 1.1rem}

/* ---------- buttons ------------------------------------------------------
   One look, everywhere: "Explore the tree", "Book a consultation", "Sign up",
   "Add to cart", "Checkout", the format chips, the quantity steppers, FLIP.
   Every one of them rests on --btn-face with a --line-btn outline, and fills
   with accent on hover, focus or press.

   Rest and hover are two different jobs. Rest only has to say "this is a
   button" — which means being visibly lighter than whatever it sits on, not
   just outlined; an outline alone still read as a hole in the page. Hover says
   "this is happening now".

   Hover lights in TWO stages, and the second is what gives the first its
   meaning. A card warming under the pointer takes its Add button to --accent:
   near, not chosen. Putting the pointer on the button itself takes it to
   --accent-hot: chosen. Buttons with no card around them skip straight to the
   second stage, which is why --accent-hot is the hover colour everywhere and
   --accent belongs to the card.

   Both stages ease in over --lit rather than the .2s the resting rule carries,
   so a button warms slower than it cools. The slow direction is the one being
   watched; the fast one happens behind a pointer already somewhere else.

   .solid and .ghost are kept as aliases so existing markup keeps working —
   they no longer differ, and neither is transparent any more.

   The header cart button is deliberately NOT in here. It's a persistent status
   control rather than a page action, and it needs to stay visible against the
   bar without a hover. */
.btn,.quick,.cart-go{
  display:inline-block;text-align:center;text-decoration:none;cursor:pointer;
  font:inherit;font-weight:600;font-size:.92rem;
  padding:.8rem 1.5rem;border-radius:2px;
  background:var(--btn-face);color:var(--ink);border:1px solid var(--line-btn);
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
.btn:hover,.btn:focus-visible,
.quick:hover:not(:disabled),
.cart-go:hover:not(:disabled){
  background:var(--accent-hot);border-color:var(--accent-hot);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
.btn.solid,.btn.ghost{background:var(--btn-face);color:var(--ink);border-color:var(--line-btn)}
.btn.solid:hover,.btn.ghost:hover{
  background:var(--accent-hot);border-color:var(--accent-hot);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}

/* Andrew's section dividers: a hairline pushed out past the section's own
   padding, so the bands read as separate planes rather than one long scroll. */
.quotes::before, .apps::before, .res::before, .ks::before, .mail::before {
  content: "";
  display: block;
  width: 100%;
  height: 1px;
  background: #320E25;
  position: relative;
  bottom: 2.5rem;
}

.quotes::after, .apps::after, .res::after, .mail::after {
  content: "";
  display: block;
  width: 100%;
  height: 1px;
  background: #320E25;
  position: relative;
  top: 2.5rem;
}

/* ---------- hero -------------------------------------------------------- */
.hero{
  display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  border-bottom:1px solid var(--line);padding:0;
}
.hero-text{padding:4.5rem 2.6rem;display:flex;flex-direction:column;justify-content:center;
  border-right:1px solid var(--line)}
.hero h1{font-size:clamp(2.3rem,4.4vw,3.7rem);line-height:1;margin-bottom:1.3rem}
.hero h1 i{font-style:italic;font-weight:400}
.lede{font-size:1rem;line-height:1.75;color:var(--ink-soft);margin:0 0 1.9rem;max-width:32rem}
.ctas{display:flex;gap:.6rem;flex-wrap:wrap}
.free{margin:.9rem 0 0;font-size:.82rem;color:var(--ink-faint)}

.hero-tree{padding:1.6rem;background:var(--plum-panel);
  display:flex;flex-direction:column;justify-content:center}
.tree-frame{position:relative;width:100%;aspect-ratio:3/2;overflow:hidden;
  border:1px solid var(--line-soft)}
.tree-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.tree-bg{z-index:1;pointer-events:none}
.tree-widget{z-index:2;background:transparent}

/* Hints sit on top of the tree, in the corners, and only after someone
   reaches for it — so the frame gets the whole panel until then. */
.tree-hint{
  position:absolute;bottom:0;z-index:3;max-width:min(17rem,46%);
  padding:1.6rem 1rem 1rem;font-size:.83rem;line-height:1.45;color:var(--ink-mute);
  opacity:0;transform:translateY(8px);
  transition:opacity .32s cubic-bezier(.65,0,.35,1),transform .32s cubic-bezier(.65,0,.35,1);
}
.tree-hint.on{opacity:1;transform:none}
.tree-hint p{margin:0}
.tree-hint a{color:var(--accent-text);text-decoration:none;
  border-bottom:1px solid rgba(255,157,194,.35)}
.tree-hint a:hover{border-color:var(--accent-text)}
.tree-hint-l{left:0;background:linear-gradient(to top right,rgba(23,4,16,.92),rgba(23,4,16,0) 78%)}
.tree-hint-r{right:0;text-align:right;display:flex;flex-direction:row-reverse;
  align-items:flex-end;gap:.7rem;
  background:linear-gradient(to top left,rgba(23,4,16,.92),rgba(23,4,16,0) 78%)}
.appicon{width:44px;height:44px;border-radius:11px;flex:none}

/* On a phone the corners are too tight — both hints come up as a sheet. */
.hint-sheet{position:fixed;inset:0;z-index:120;display:grid;place-items:end center;
  background:rgba(10,2,7,.55);opacity:0;transition:opacity .28s ease}
.hint-sheet.on{opacity:1}
.hint-sheet-in{width:100%;background:var(--plum-deep);border-top:1px solid var(--line);
  padding:1.4rem 1.3rem calc(1.4rem + env(safe-area-inset-bottom));
  transform:translateY(100%);transition:transform .3s cubic-bezier(.65,0,.35,1)}
.hint-sheet.on .hint-sheet-in{transform:none}
.hint-sheet p{margin:0 0 .9rem;font-size:1rem}
.hint-sheet a{color:var(--accent-text);text-decoration:none;
  display:inline-flex;align-items:center;gap:.55rem}
.hint-sheet a .res-icon{flex:none;color:var(--ink-faint)}
.hint-sheet button{width:100%;margin-top:.4rem;background:var(--btn-face);border:1px solid var(--line-btn);
  color:var(--ink);padding:.75rem;border-radius:2px;font-size:.9rem;cursor:pointer}

/* ---------- quotes ------------------------------------------------------ */
/* Each quote is a full-width layer. The outgoing one flies off to the left
   while the next arrives from the right, both on the same S-curve. They stack
   in one grid cell, so the section is as tall as the tallest quote and nothing
   reflows mid-flight. */
.quotes{border-bottom:1px solid var(--line);overflow:hidden}
.quote-stage{position:relative;display:grid;width:100%}
.quote{
  grid-area:1/1;margin:0;
  opacity:0;transform:translate3d(110%,0,0);pointer-events:none;
  transition:transform .62s cubic-bezier(.65,0,.35,1),opacity .42s ease;
  will-change:transform;
}
.quote.is-current{opacity:1;transform:translate3d(0,0,0);pointer-events:auto}
.quote.out-left{opacity:0;transform:translate3d(-110%,0,0)}
.quote.out-right{opacity:0;transform:translate3d(110%,0,0)}
.quote.no-anim{transition:none}
.quote-in{max-width:var(--maxw);margin:0 auto;padding:0 1.5rem}
.quote blockquote{margin:0;font-family:'Fraunces',Georgia,serif;font-weight:400;
  font-size:clamp(1.3rem,2.6vw,1.9rem);line-height:1.34;max-width:46rem}
.quote figcaption{margin-top:.9rem;font-size:.88rem;color:var(--ink-mute)}
.quote figcaption span{color:var(--ink-faint)}
.quote-nav{display:flex;align-items:center;gap:.9rem;margin-top:1.7rem}
.quote-nav > button{background:none;border:none;color:var(--ink-faint);font-size:1.5rem;
  line-height:1;cursor:pointer;padding:.1rem .3rem}
.quote-nav > button:hover{color:#fff}
.dots{display:flex;gap:.4rem}
.dots button{width:8px;height:8px;padding:0;border-radius:50%;border:none;
  background:#5d2143;cursor:pointer;transition:background .2s}
.dots button[aria-current="true"]{background:var(--accent-text)}

/* ---------- shop -------------------------------------------------------- */
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1.3rem}
/* The card is only the frame the turn happens in — no fill, no border, no
   padding of its own. All of that sits on the two faces instead, which is what
   makes the WHOLE card rotate rather than the contents inside a box that
   stays put. */
.card{display:flex;flex-direction:column}
.shot{aspect-ratio:4/5;background:var(--plum-well);border:1px solid rgba(255,255,255,.06);
  margin-bottom:.9rem;overflow:hidden}
.shot img{width:100%;height:100%;object-fit:cover}
.card h3{font-size:1.12rem;margin-bottom:.25rem}
.price{color:var(--accent-text);font-size:.92rem;margin:0}
.card-blurb{margin:.5rem 0 0;font-size:.85rem;color:var(--ink-mute);line-height:1.55}
/* A blurb is written by hand in the config, so it may carry a link —
   "Learn more" and the like. Without this they'd inherit the muted grey and
   read as ordinary text. */
.card-blurb a{color:var(--accent-text);text-decoration:none;
  border-bottom:1px solid rgba(255,157,194,.35)}
.card-blurb a:hover{border-color:var(--accent-text)}
.fmt{display:flex;gap:.35rem;margin-top:.8rem;flex-wrap:wrap}
.fmt button{background:var(--btn-face);border:1px solid var(--line-btn);color:var(--ink-soft);
  font-size:.75rem;padding:.32rem .55rem;cursor:pointer;border-radius:2px}
.fmt button[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#fff}
.fmt button:disabled{opacity:.4;cursor:not-allowed;text-decoration:line-through}
.fmt-note{margin:.55rem 0 .55rem 0 ;font-size:.78rem;color:var(--ink-faint);min-height:1.1em}

/* Product options — signed or not, and the message that goes with it. */
.opts{margin:.9rem 0 .9rem 0;padding-top:.85rem;border-top:1px solid var(--line-soft)}
.opt{margin-bottom:.7rem}
.opt:last-child{margin-bottom:0}
.opt-label{display:block;font-size:.75rem;color:var(--ink-faint);margin-bottom:.35rem}
.opt-label i{font-style:normal;color:var(--accent-text);font-size:.7rem;margin-left:.3rem}
.opt-choices{display:flex;gap:.35rem;flex-wrap:wrap}
.opt-choices button{background:var(--btn-face);border:1px solid var(--line-btn);color:var(--ink-soft);
  font:inherit;font-size:.75rem;padding:.32rem .55rem;cursor:pointer;border-radius:2px}
.opt-choices button[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#fff}
.opt input[type="text"]{width:100%;background:var(--plum-well);border:1px solid #5d2143;
  color:var(--ink);font:inherit;font-size:.82rem;padding:.45rem .55rem;border-radius:2px}
.opt input[type="text"]::placeholder{color:#9a6c84}

/* Add sits in its own row at the bottom of the card. It rests as a ghost
   button — dark, outlined, the same weight as the rest of the card — and warms
   to solid accent once the card is being used: hovered, focused, or the moment
   a format or option is chosen. It keeps its space either way, so nothing
   under it is ever covered and nothing jumps. */
.quick{margin-top:auto;width:100%;padding:.72rem;font-size:.88rem}
.card > .quick{margin-top:1rem}
.card:hover .quick,
.card.engaged .quick{
  background:var(--accent);border-color:var(--accent);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
/* Keyboard focus lights it too, but :focus-VISIBLE, and in a rule of its own.
   :focus-within also fires for a mouse click — pressing FLIP or a format left
   the button burning on a card nobody was pointing at any more, which is the
   state that looked stuck. Separate rule so a browser without :has() still
   gets the hover and engaged cases above. */
.card:has(:focus-visible) .quick{
  background:var(--accent);border-color:var(--accent);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
/* Stage two, on the button itself. The card states above are named again here
   beside :hover because they carry the same weight — without that, .card:hover
   .quick wins on source order and the pointer landing on the button changes
   nothing, which is how this looked before. :not(:disabled) keeps a sold-out
   or unchosen button dark: it has nothing to light up for. */
.quick:hover:not(:disabled),
.card:hover .quick:hover:not(:disabled),
.card.engaged .quick:hover:not(:disabled),
.card:has(:focus-visible) .quick:hover:not(:disabled){
  background:var(--accent-hot);border-color:var(--accent-hot);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
.quick:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}


/* Nothing to buy: stays quiet no matter what the card is doing. */
.quick:disabled,
.quick.soon,
.card:hover .quick:disabled,
.card.engaged .quick:disabled{
  background:transparent;border-color:#4a1935;color:var(--ink-faint);cursor:default;
}
.card:has(:focus-visible) .quick:disabled{
  background:transparent;border-color:#4a1935;color:var(--ink-faint);cursor:default;
}

/* ---------- featured card -----------------------------------------------
   The bundle: full width under the grid, photo beside the words rather than
   above them. It carries .card too, so the Add button's resting, warmed and
   disabled states above apply unchanged; everything below only reshapes it.

   Set apart from the grid by two things only: the width, and an outline in
   the button line colour instead of the grid's near-invisible hairline. The
   fill is the same card face, so it still reads as part of the same shop. */
.card.feature{
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:2rem;
  align-items:stretch;margin-top:1.3rem;padding:1.4rem;
  background:var(--card-face);border:1px solid var(--line-btn);
}
.card.feature.no-shot{grid-template-columns:minmax(0,1fr)}
/* Ecwid's photo at its own shape: no crop, no forced ratio. */
.feature-shot{align-self:start; /* background:var(--plum-well); */
  border:1px solid rgba(255,255,255,.06);overflow:hidden}
.feature-shot img{width:100%;height:auto}
.feature-body{display:flex;flex-direction:column;min-width:0}
.card.feature h3{font-size:clamp(1.4rem,2.4vw,1.85rem);line-height:1.15;margin-bottom:.35rem}
.card.feature .price{font-size:1.02rem}
/* The whole description, so a readable measure and a touch more size than
   the back of a grid card. List and heading styling comes from .back-copy. */
.card.feature .feature-copy{font-size:.93rem;max-width:62ch;padding-top:1rem;margin-bottom:1.5rem}
/* margin-top:auto sinks the button to the foot of the column, level with
   the bottom of the photo when the copy is shorter than it. */
.card.feature .quick{margin-top:auto;width:auto;min-width:13rem;align-self:flex-start;
  padding:.8rem 1.6rem}

@media (max-width:720px){
  .card.feature{grid-template-columns:minmax(0,1fr);gap:1.1rem;padding:1rem}
  .card.feature .quick{width:100%;min-width:0;align-self:stretch}
}

/* Touch has no hover to warm the button, so it used to arrive pre-filled
   solid on every phone — permanently in the "just pressed" look before anyone
   had touched it, which is what read as stuck. It now rests exactly like
   every other button: ghost until engaged, on every input type. */

/* ---------- flip card ----------------------------------------------------
   The front is the shop card as it always was; the back carries the product
   description written in Ecwid, plus that product's other photos as a reel.

   Two things make this behave. First, both faces are OPAQUE and separated on
   the z axis, so whichever is facing you covers the other — backface-visibility
   alone left the front's text showing through the back, mirrored. Second, the
   turn is driven by --turn, which only ever counts up: every press adds another
   180°, so the card always rotates the same way instead of winding back. */
.card{position:relative;perspective:1600px}
.card-flip{
  position:relative;display:flex;flex-direction:column;flex:1;
  transform-style:preserve-3d;-webkit-transform-style:preserve-3d;
  transform:rotateY(var(--turn,0deg));
  transition:transform .62s cubic-bezier(.65,0,.35,1);
}
.face{
  position:relative;
  display:flex;flex-direction:column;flex:1;
  background:var(--card-face);
  border:1px solid var(--line-soft);padding:1rem;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
}
/* 1px of depth settles which face is in front; without it the two sit on the
   same plane and the browser picks for us. */
.face-front{transform:translateZ(1px)}
.face-back{
  position:absolute;inset:0;
  transform:rotateY(180deg) translateZ(1px);
}
/* The back's scrolling happens on an inner box rather than on the face, so the
   BACK tab can hang off the card's edge the way FLIP does — a scroll container
   clips anything that reaches outside it.

   min-height:0 is what makes it actually scroll: a flex child won't shrink
   below its content without it, and the description would push the Add button
   off the bottom of the card instead. */
.back-scroll{
  display:flex;flex-direction:column;flex:1;min-height:0;
  overflow-y:auto;overscroll-behavior:contain;
}

/* The Add button on the back sits BELOW the scrolling copy, not inside it, so
   the description always ends just above it and the button never scrolls away.
   flex:none stops it being squeezed when the copy is long. */
.face-back > .quick{flex:none;margin-top:.9rem}

/* There is a tab on EACH face now — FLIP on the front, BACK on the far side —
   both inside the rotating box, so the tab turns with the card instead of
   hovering over it. They sit at the same coordinates in their own face, and
   the back face reads at 360° once the card has turned, so nothing is
   mirrored and the tab appears not to move at all through the flip.

   .flip-anchor is an invisible box repeating the photo's geometry (the card's
   1rem padding, the 4/5 aspect), so the tab hangs off the photo's bottom-right
   corner without hard-coding a height that breaks at the next grid width. */
.flip-anchor{
  position:absolute;z-index:5;pointer-events:none;
  top:1.7rem;left:1.5rem;width:calc(100% - 2rem);aspect-ratio:4/5;
}
.flip-tab{
  position:absolute;top:100%;right:calc(-1rem - 7px);
  transform:translateY(-42%);pointer-events:auto;
  /* Upright letters stacked downward — F, L, I, P — rather than one word
     turned on its side. text-orientation keeps each glyph the right way up. */
  writing-mode:vertical-rl;text-orientation:upright;
  -webkit-writing-mode:vertical-rl;-webkit-text-orientation:upright;
  /* Same treatment as every other button: --btn-face at rest, filling with
     accent on hover. The solid fill matters doubly here — it overlaps the
     photo's bottom edge, and anything transparent would show the picture
     through the button. Text stays dulled (--ink-faint) on purpose. */
  background:var(--btn-face);color:var(--ink-faint);border:1px solid var(--line-btn);
  border-radius:2px;
  font:inherit;font-size:.58rem;font-weight:700;letter-spacing:.13em;
  line-height:1;padding:.6rem .34rem;cursor:pointer;
  box-shadow:0 3px 12px rgba(0,0,0,.45);
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
/* Only its own pointer lights it up — hovering anywhere on the card would
   have it reading as pressed before anyone reached for it. */
.card.flipped .flip-tab{background:var(--accent-half);border-color:var(--accent-half);color:#fff}
.flip-tab:hover,
.card.flipped .flip-tab:hover{
  background:var(--accent-hot);border-color:var(--accent-hot);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
.flip-tab:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

.back-head{margin-bottom:.2rem}
.back-head h3{font-size:1.12rem}
.back-fmt{margin:1rem 0 .1rem;font-size:.75rem;color:var(--ink-faint);
  letter-spacing:.06em;text-transform:uppercase}
.back-copy{font-size:.86rem;line-height:1.65;color:var(--ink-soft);padding-top:.6rem}
.back-copy > :first-child{margin-top:0}
.back-copy p{margin:0 0 .7rem}
.back-copy ul,.back-copy ol{margin:0 0 .7rem;padding-left:1.1rem}
.back-copy li{margin-bottom:.3rem}
.back-copy h3,.back-copy h4,.back-copy h5,.back-copy h6{
  font-size:.95rem;margin:1rem 0 .4rem;color:var(--ink)}
.back-copy a{color:var(--accent-text)}
.back-empty{color:var(--ink-faint);font-style:italic}

/* ---------- photo reel ---------------------------------------------------
   Gallery shots are mostly landscape, so the reel is a wider box than the
   4/5 the front's product shot uses — otherwise a landscape photo sits in a
   tall frame with the card's fill above and below it.

   Swiping is CSS scroll-snap. The arrows are for pointers only and appear on
   hover; ct.js keeps the dots in step and hides an arrow with nowhere to go. */
/* position:relative so the arrows measure against the photo rather than the
   whole face, and overflow:visible so the part of them that hangs below the
   picture isn't cut off. The reel clips its own photos, so nothing escapes. */
.shot-carousel{position:relative;aspect-ratio:3/2;margin-bottom:0;overflow:visible}
.reel{
  display:flex;height:100%;
  overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;
}
.reel::-webkit-scrollbar{display:none}
.reel img{flex:0 0 100%;width:100%;height:100%;object-fit:cover;scroll-snap-align:center}

.reel-nav{
  /* They sit on the photo's bottom edge, raised just enough that a quarter of
     the button laps onto the picture and the other three quarters hang below
     it, out of the way of what's in the shot. --nav-h is here so the quarter
     is worked out from whatever height the button actually has: the zoom uses
     a bigger one and gets the same proportion for free. */
  --nav-h:2.3rem;
  position:absolute;z-index:3;
  top:calc(100% - var(--nav-h) * .25);
  width:1.9rem;height:var(--nav-h);padding:0;
  display:grid;place-items:center;
  background:var(--btn-face);border:1px solid var(--line-btn);
  color:var(--ink);font:inherit;font-size:1.2rem;line-height:1;
  border-radius:2px;cursor:pointer;
  opacity:0;transition:opacity .18s ease,background .2s ease,border-color .2s ease;
}
/* They hang below the photo now, so the pointer can reach one without ever
   crossing the picture — the button's own hover counts as well. */
.shot-carousel:hover .reel-nav,
.reel:focus-visible ~ .reel-nav,
.reel-nav:hover,
.reel-nav:focus-visible{opacity:1}
/* Appearing at all is their first stage — the card has to be hovered before
   they exist. So their own hover goes straight to the second. */
.reel-nav:hover{
  background:var(--accent-hot);border-color:var(--accent-hot);
  transition:background var(--lit) ease,border-color var(--lit) ease;
}
.reel-prev{left:.45rem}
.reel-next{right:.45rem}
/* No pointer, no arrows — the reel is swiped instead. The zoom keeps its
   pair, though: a single photo in a frame doesn't announce itself as
   swipeable the way a reel does, and without them the only sign there's
   another shot is a row of 7px dots. */
@media (hover:none){
  .reel-nav{display:none}
  .lightbox .reel-nav{display:grid}
}

/* Directly under the photo, with the copy below them. Same dots as the quote
   carousel, so the two read as the same control. The margin lines their
   centres up with the arrows now hanging off the photo's bottom edge, so the
   three read as one row: back, position, forward. */
.reel-dots{display:flex;justify-content:center;gap:.4rem;margin:.36rem 0 .55rem}
.reel-dots span{
  width:7px;height:7px;border-radius:50%;cursor:pointer;
  background:#5d2143;transition:background .2s ease;
}
.reel-dots span.on{background:var(--accent-text)}

/* ---------- photo zoom ---------------------------------------------------
   Click a photo on the back of a card and it opens full size over a darkened
   page, with the same arrows and dots the reel has. */
.lightbox{
  position:fixed;inset:0;z-index:130;
  display:grid;place-items:center;padding:clamp(1.6rem,4vw,3rem);
  background:rgba(8,1,5,.86);backdrop-filter:blur(3px);
  opacity:0;transition:opacity .24s ease;
}
.lightbox.on{opacity:1}
.lightbox-in{
  /* A set width, not a shrink-to-fit one. The column used to size itself to
     whatever photo was in it, so every arrow and the close button moved as you
     stepped through the reel. */
  position:relative;display:flex;flex-direction:column;align-items:center;gap:.55rem;
  width:min(1000px,100%);max-height:100%;
}
/* THE FRAME.
   Fixed height as well as width, so the box the arrows measure against is the
   same box for every shot in the reel — the column used to size itself to the
   photo, which is what had everything shifting as you stepped through.

   The photo sits on the frame's floor rather than centred in it, so its bottom
   edge lands in the same place whatever its shape. That's what lets the arrows
   keep the quarter-overlap they have on the card AND stay put. The bottom
   strip is the room they hang into: the whole button stays inside the frame
   rather than over the backdrop, where a near-miss used to land on the veil
   and shut the zoom. */
.lightbox-stage{
  position:relative;display:flex;align-items:flex-end;justify-content:center;
  width:100%;height:74vh;min-height:0;
  padding-bottom:calc(3rem * .75);
}
.lightbox-stage img{
  max-width:100%;max-height:100%;width:auto;height:auto;
  border-radius:4px;border:1px solid rgba(255,255,255,.14);
  box-shadow:0 24px 60px rgba(0,0,0,.6);background:var(--plum-well);
}
/* The arrows here are always visible — there's no card to hover first. They
   sit on the bottom edge of the frame, lapping onto the photo by the same
   quarter as on the card, and they hold that spot whatever size the photo
   coming next happens to be. */
.lightbox .reel-nav{opacity:1;--nav-h:3rem;width:2.4rem;font-size:1.5rem}
.lightbox .reel-nav{top:auto;bottom:0}
.lightbox .reel-prev{left:.6rem}
.lightbox .reel-next{right:.6rem}
.lightbox-close{
  position:absolute;top:-.4rem;right:-.4rem;transform:translate(50%,-50%);
  z-index:4;width:2.2rem;height:2.2rem;padding:0;
  display:grid;place-items:center;
  background:var(--btn-face);color:var(--ink);border:1px solid var(--line-btn);
  border-radius:50%;font:inherit;font-size:1.35rem;line-height:1;cursor:pointer;
  transition:background .2s ease,border-color .2s ease,color .2s ease;
}
.lightbox-close:hover{
  background:var(--accent-hot);border-color:var(--accent-hot);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
.lightbox .reel-dots{margin:0}

/* The photos on a card invite the click. */
.reel img[data-zoom]{cursor:zoom-in}

/* ---------- apps + lessons ---------------------------------------------- */
/* A section heading with its own action on the same line. The h2 sits inside
   this row rather than directly in .wrap, so it no longer matches the
   `section > .wrap > h2` rule that gives headings their size and bottom
   margin — the row carries the margin and the sizes are restated here. Wraps
   to two lines on a narrow screen rather than squashing the button. */
.sec-head{display:flex;align-items:center;justify-content:space-between;
  gap:1rem 1.2rem;flex-wrap:wrap;margin-bottom:1.5rem}
.sec-head h2{font-size:1.95rem;margin:0}
.apps .sec-head h2{font-size:1.6rem}
/* Smaller than a standalone call to action — it sits beside a heading, not in
   its own row. Everything else about it is the shared button. */
.sec-head .btn{padding:.55rem 1.1rem;font-size:.85rem}

.apps{background:var(--plum-deep);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line)}
.apps h2{font-size:1.6rem}
.pair{display:grid;grid-template-columns:repeat(auto-fit,minmax(270px,1fr));gap:1rem}
.app{display:flex;gap:1rem;align-items:center;background:var(--plum);
  border:1px solid var(--line);padding:1.1rem;text-decoration:none}
.app:hover{border-color:var(--accent)}
.app b{display:block;font-family:'Fraunces',Georgia,serif;font-weight:600;font-size:1.05rem}
.app em{font-style:normal;font-size:.83rem;color:var(--ink-faint)}
.app .appicon{width:56px;height:56px;border-radius:13px}

/* Screenshots under each app, pulled live from the App Store listing. Laid out
   as columns so three or four both fill the row evenly. */
.app-card{display:flex;flex-direction:column;gap:.7rem}
.shots{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:.5rem}
.shots img,.shot-placeholder{
  width:100%;aspect-ratio:9/16;border-radius:7px;
  background:var(--plum-well);border:1px solid var(--line);
}
.shots img{object-fit:cover;object-position:top}
.shot-placeholder{
  display:grid;place-items:center;border-style:dashed;border-color:#5d2143;
  color:var(--ink-faint);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;
}

.lessons .wrap{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2rem;align-items:center}
.lessons h2{font-size:1.7rem;margin-bottom:.5rem}
.lessons p{margin:0;font-size:.94rem;color:var(--ink-mute);line-height:1.65;max-width:40rem}

/* ---------- kickstarter ------------------------------------------------- */
.ks .wrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr);
  gap:2.4rem;align-items:center}
.ks h2{font-size:1.7rem;margin-bottom:.6rem}
.ks p{margin:0;font-size:.94rem;color:var(--ink-mute);line-height:1.7}
.video{position:relative;aspect-ratio:16/9;background:var(--plum-well);
  border:1px solid var(--line);overflow:hidden}
.video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}

/* ---------- resources --------------------------------------------------- */
.res ul{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.res li{border-bottom:1px solid var(--line)}
.res a{display:flex;gap:.85rem;align-items:center;padding:1rem .2rem;text-decoration:none}
/* The kind is spelled out at the far end of the row, which is the last place
   the eye lands. The glyph says it at the start. */
.res-icon{flex:none;color:var(--ink-faint);transition:color .18s ease}
.res a:hover .res-icon{color:var(--accent-text)}
.res a:hover{background:rgba(255,255,255,.03)}
.res b{font-weight:500;font-size:1rem}
.res em{font-style:normal;margin-left:auto;font-size:.82rem;color:var(--ink-faint);white-space:nowrap}

/* ---------- bio --------------------------------------------------------- */
.bio .wrap{display:grid;grid-template-columns:12rem minmax(0,1fr);gap:2.4rem;align-items:start}
.portrait{aspect-ratio:1;background:var(--plum-well);border:1px solid var(--line);
  border-radius:50%;overflow:hidden}
.portrait img{width:100%;height:100%;object-fit:cover}
.bio h2{font-size:1.6rem;margin-bottom:.8rem}
.bio p{margin:0 0 .9rem;font-size:.95rem;line-height:1.75;color:var(--ink-soft);max-width:44rem}

/* ---------- mailing list ------------------------------------------------ */
.mail{background:var(--plum-deep);border-top:1px solid var(--line)}
.mail .wrap{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:1.4rem;align-items:center}
.mail h2{font-size:1.4rem;margin-bottom:.3rem}
.mail p{margin:0;font-size:.88rem;color:var(--ink-faint)}
.field{display:flex;gap:.5rem;flex-wrap:wrap;position:relative}
.field input{background:var(--plum);border:1px solid #5d2143;color:var(--ink);
  padding:.78rem .9rem;font:inherit;font-size:.9rem;min-width:15rem;border-radius:2px}
.field input::placeholder{color:#9a6c84}

/* ---------- checkout handoff -------------------------------------------
   Ecwid draws its own storefront inside the container and, in doing so,
   REWRITES that element's class attribute — so .ecwid-host stops existing the
   moment the store renders, and any styling hung on it disappears with it.
   Everything below therefore hangs off .checkout (ours, on the section, which
   Ecwid never touches) and off the container's id, which Ecwid does keep.

   Ecwid's storefront assumes a light ground: its type is dark grey and its
   rules are near-white. We're putting it on plum instead, so the whole trick
   here is the safety net a few rules down — a blanket `color: inherit` on
   text-bearing elements. Anything Ecwid renames, or ships next month, still
   inherits legible ink rather than turning into dark grey on dark plum. The
   named rules underneath are polish; the net is what keeps it readable.
   ---------------------------------------------------------------------- */

.checkout{padding:0 0 4rem;background:var(--plum)}

/* Dark band across the top, so the page has a head before the store begins. */
.checkout-top{background:var(--plum-deep);border-bottom:1px solid var(--line);
  padding:1.7rem 0 1.6rem;margin-bottom:2.2rem}
.checkout-top h1{font-size:1.6rem;margin:0 0 .35rem}
.checkout-top p{margin:0;color:var(--ink-mute);font-size:.92rem;max-width:46ch}
.checkout-back{margin:0 0 .9rem}
.checkout-back a{color:var(--ink-mute);text-decoration:none;font-size:.88rem}
.checkout-back a:hover{color:var(--accent-text)}

/* THE PANEL.
   The same plum, lifted a step — brighter and warmer than the page so it feels
   like somewhere to settle in and finish, without leaving the scheme. Matched
   on the id as well as the class: the class is gone by the time the store has
   drawn itself, the id survives.

   Ecwid paints its own ground inside the panel, in the page's own dark plum,
   which stopped dead at our padding and drew a hard rectangle inside the
   frame. That ground is switched off a few rules down and redrawn here as a
   soft centre instead: dark where the store is, easing up to the panel's own
   colour as it reaches the edge, so there's no line to see. */
.checkout .ecwid-host,
.checkout [id^="my-store-"]{
  min-height:60vh;
  background:
    radial-gradient(125% 92% at 50% 46%,
      rgba(37,9,26,1) 0%,
      rgba(37,9,26,.96) 38%,
      rgba(37,9,26,.62) 68%,
      rgba(37,9,26,.22) 87%,
      rgba(37,9,26,0) 100%),
    linear-gradient(180deg,#33132b 0%,#2b0e23 100%);
  color:#f3e6ee;
  padding:2.1rem 2.3rem;
  border-radius:6px;
  border:1px solid rgba(255,255,255,.13);
  box-shadow:0 16px 44px rgba(0,0,0,.42),inset 0 1px 0 rgba(255,255,255,.07);
}

.checkout-wait{color:var(--ink-mute);font-size:.95rem;margin:0}
.checkout-fine{margin:1.3rem 0 0;font-size:.82rem;color:var(--ink-mute)}
.checkout-fine a{color:var(--accent-text)}

/* --- undo the global resets that reach inside the store -----------------
   These are set on bare elements at the top of this file, so they cross into
   Ecwid's markup and quietly break its spacing. Put them back. */
.checkout h1,.checkout h2,.checkout h3,
.checkout h4,.checkout h5,.checkout h6{
  font-family:inherit;font-weight:600;letter-spacing:normal;margin:revert;
}
.checkout-top h1{font-family:'Fraunces',Georgia,serif;letter-spacing:-.015em;margin:0 0 .35rem}
.checkout [id^="my-store-"] button{font:revert}
.checkout [id^="my-store-"] img{display:inline-block;max-width:100%;height:auto}
.checkout [id^="my-store-"] [hidden]{display:none}

/* --- OVERRIDING ECWID: THE SPECIFICITY TIERS ----------------------------
   Ecwid generates a storefront sheet from the owner's design settings and
   marks its colours !important, at a higher specificity than a single-id
   selector can reach. An important declaration only loses to another
   important declaration that is MORE SPECIFIC — arriving later doesn't help.
   So these rules buy weight by repeating the id selector. It matches exactly
   the same elements and changes nothing but the arithmetic.

   Blunt, and worth naming as such. But the alternative is chasing their class
   names forever, and losing every time they ship a new one.

     NET     (0,6,0)   everything inherits legible ink
     FORM    (0,7,0)   fields, buttons, borders, icons
     TONE    (0,8,0)   the few things that shouldn't be plain ink
     STATUS  (0,9,0)   errors and confirmations, which must outrank tone

   The gap above Ecwid is deliberate headroom. A tie goes to THEM, because
   their sheet is injected after ours, so matching their weight isn't enough —
   we have to clear it. Measured: their heading rules behave like (0,3,0), and
   this ladder holds until they reach (0,7,0), which they have no reason to.

   Keep the tiers in that order if you edit this. The net is deliberately
   heavier than Ecwid and deliberately LIGHTER than tone: get that backwards
   and every price, link and error flattens into body text.

   One trap worth flagging: chaining `:not(x):not(y):not(z)` adds each one's
   weight, which is how an earlier version of this block reached (0,8,10) and
   silently ate its own tone rules. A single `:not(x, y, z)` counts only its
   most specific argument. That's why the exclusions below are one list.
   ------------------------------------------------------------------------ */

/* NET. `*` rather than a list of tag names, so custom elements and anything
   they invent later are covered too. Form controls and the payment brands are
   excluded: they carry their own backgrounds, and because `inherit` reads from
   the parent, their contents keep the right colour automatically. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] *:not(button, input, select, textarea, svg, path, g, use, img, iframe,
  [class*="paypal" i], [class*="gpay" i], [class*="google-pay" i],
  [class*="applepay" i], [class*="apple-pay" i]){
  color:inherit !important;
}

/* NET, second half: grounds. Same idea and same tier as the colour net above.
   Ecwid fills its containers with a flat colour of its own, and because those
   containers sit inside our padding the fill ended as a hard-edged rectangle
   floating in the panel. Clearing it lets the panel's own gradient show
   through the whole thing, edge included.

   background-COLOR only, so the few things Ecwid draws as background images —
   the padlock by the TLS line, chiefly — survive. Controls and the payment
   brands are excluded for the same reason as above: they carry a ground on
   purpose. Ribbons keep theirs from the tone tier, which outweighs this.

   Swatches are excluded too. Ecwid draws a colour or pattern option as a
   background-colour on a plain element, so without this a swatch would render
   as an empty outline the day you add one. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] *:not(button, input, select, textarea, svg, path, g, use, img, iframe,
  [class*="paypal" i], [class*="gpay" i], [class*="google-pay" i],
  [class*="applepay" i], [class*="apple-pay" i],
  [class*="ribbon" i], [class*="__tag" i], [class*="badge" i],
  [class*="swatch" i], [class*="colorpicker" i]){
  background-color:transparent !important;
}

/* --- TONE ---------------------------------------------------------------
   Everything is legible by default now, so put the hierarchy back. */

/* Headings. Ecwid numbers these h1–h6 as CLASSES whatever tag it actually
   uses, which is why naming .ec-header-h1 alone left "Next", "Shipping
   options" and "You may also like" behind. Cover the whole run. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(
  .ec-page-title, .ec-header-h1, .ec-header-h2, .ec-header-h3,
  .ec-header-h4, .ec-header-h5, .ec-header-h6,
  .ec-cart__title, .ec-store__title, .ec-related-products__title
){color:#f3e6ee !important}

/* Secondary and explanatory copy. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(
  .ec-text-muted, .ec-cart-item__sku, .ec-breadcrumbs, .ec-cart-item__count,
  .ec-cart-email__text, .ec-cart-next-step__text, .ec-cart__note,
  .ec-notice, .ec-form__msg, .form-control__placeholder,
  .ec-cart-summary__note, .ec-cart-next-step__title
){color:#c299b1 !important}

/* Money. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(
  .ec-cart-item__price, .ec-cart-summary__row, .ec-cart-summary__total,
  .ec-price-item, .ec-cart-item__total
){color:#ff9dc2 !important}

/* Links, and anything nested inside one. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] a,
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] a *{color:#ff9dc2 !important;text-decoration:none}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] a:hover,
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] a:hover *{color:#fff !important;text-decoration:underline}

/* --- STATUS -------------------------------------------------------------
   Above tone on purpose: Ecwid's error class usually rides alongside a muted
   one, and a validation error nobody can see is worse than an ugly one. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where([class*="error" i], [class*="invalid" i], [class*="warning" i]),
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where([class*="error" i], [class*="invalid" i]) *{color:#ff8a8a !important}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where([class*="success" i]){color:#7ee0a8 !important}

/* --- product ribbons -----------------------------------------------------
   Ecwid stamps "SALE", "NEW", "OUT OF STOCK" and the like onto product photos
   as small tags, coloured from its own palette — which on this ground came out
   as a pale block with text the same colour as the block. One treatment for
   all of them: solid accent, white, upper case, so they read alike whatever
   Ecwid decides to call each one. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where([class*="ribbon" i], [class*="__tag" i]){
  background:#cf0053 !important;
  color:#fff !important;
  border:none !important;
  border-radius:2px !important;
  padding:.3em .6em !important;
  font-size:.68rem !important;
  font-weight:700 !important;
  letter-spacing:.09em !important;
  text-transform:uppercase !important;
  line-height:1.45 !important;
  text-shadow:none !important;
  box-shadow:0 2px 10px rgba(0,0,0,.4) !important;
}
/* The inner span of a two-part tag mustn't paint over the outer one. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where([class*="ribbon" i], [class*="__tag" i]) *{
  background:transparent !important;color:#fff !important;box-shadow:none !important;
}

/* --- icons --------------------------------------------------------------
   Inline SVG follows the text. The padlock beside the TLS line is not inline
   SVG though — it's a dark monochrome background image, which no colour rule
   can reach, so on this ground it vanished rather than went grey. Inverting it
   is the only way back short of hosting our own copy. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] svg{fill:currentColor;stroke:currentColor}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(button, a[class*="pay" i]) svg{fill:revert;stroke:revert}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where([class*="lock" i], [class*="secure" i], [class*="ssl" i]){
  filter:invert(1) brightness(1.85);
}

/* Dividers: Ecwid's are near-white and disappear here. Longhands as well as
   border-color, because they set these with the `border` shorthand and a
   shorthand replaces every longhand it touches. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(hr, .ec-cart-item, .ec-cart-summary, .ec-cart-summary__row--total,
  .ec-cart__side, .ec-cart-next-step, .ec-related-products){
  border-color:rgba(255,255,255,.16) !important;
  border-top-color:rgba(255,255,255,.16) !important;
  border-bottom-color:rgba(255,255,255,.16) !important;
}

/* Product thumbnails.
   The wrapper Ecwid uses is a fixed box, taller and wider than the photo it
   holds, so giving IT a background painted a black slab around every thumbnail.
   Style the image instead and leave the box alone. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(.ec-cart-item__image, .ec-cart-item__image-inner){
  background:transparent !important;border:none !important;
}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(.ec-cart-item__image, .ec-cart-item__image-inner) img{
  border:1px solid rgba(255,255,255,.12);border-radius:3px;
}

/* --- FORM: fields and buttons -------------------------------------------
   Inputs match the option fields in the shop. Ecwid floats its own <label>
   over the field as the placeholder — that's why the email box read as empty,
   and why .form-control__placeholder is in the muted group above. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(
  input[type="text"], input[type="email"], input[type="tel"],
  input[type="number"], input[type="password"], input[type="search"],
  textarea, select
){
  background:#170410 !important;
  border:1px solid #6d2449 !important;
  color:#f3e6ee !important;
  border-radius:2px !important;
}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(input, textarea)::placeholder{color:#a0708b !important;opacity:1}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(input, textarea, select):focus{
  border-color:#ff9dc2 !important;
  outline:2px solid rgba(255,157,194,.35);outline-offset:1px;
}

/* The primary action in the site's accent. Scoped to the primary class only,
   so Google Pay and PayPal keep the branding they're required to keep. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(.form-control__button--primary, .ec-cart__button--primary, .ec-form__button--primary){
  background:#cf0053 !important;border-color:#cf0053 !important;color:#fff !important;
}
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(.form-control__button--primary, .ec-cart__button--primary, .ec-form__button--primary):hover{
  background:#e5195f !important;border-color:#e5195f !important;
}

/* Secondary buttons: the site's standard button, same two tokens, so a
   Continue Shopping button here reads as the same object as everywhere else
   on the domain. */
.checkout [id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"][id^="my-store-"] :where(.form-control__button--secondary, .ec-cart__button--secondary){
  background:var(--btn-face) !important;border:1px solid var(--line-btn) !important;color:#f3e6ee !important;
}

@media (max-width:720px){
  .checkout .ecwid-host,
  .checkout [id^="my-store-"]{padding:1.2rem}
  .checkout-top{padding:1.3rem 0 1.2rem;margin-bottom:1.5rem}
  .checkout-top h1{font-size:1.35rem}
}

/* ---------- cart -------------------------------------------------------- */
/* Banded the way the homepage is: a darker head and foot around a lighter
   body, so the three parts read as three parts rather than one grey slab. */
.cart-veil{position:fixed;inset:0;z-index:110;background:rgba(10,2,7,.62);
  opacity:0;transition:opacity .28s ease}
.cart-veil.on{opacity:1}
.cart-panel{
  position:fixed;top:0;right:0;bottom:0;z-index:111;width:min(24rem,92vw);
  display:flex;flex-direction:column;background:var(--plum);
  border-left:1px solid var(--line);
  box-shadow:-18px 0 44px rgba(0,0,0,.45);
  transform:translateX(100%);
  transition:transform .3s cubic-bezier(.65,0,.35,1);
}
.cart-panel.on{transform:none}

.cart-head{display:flex;align-items:center;justify-content:space-between;
  padding:1.1rem 1.2rem;background:var(--plum-deep);
  border-bottom:1px solid var(--line)}
.cart-head h2{font-size:1.25rem;color:var(--ink)}
.cart-close{background:none;border:none;color:var(--ink-mute);font-size:1.6rem;
  line-height:1;cursor:pointer;padding:0 .2rem}
.cart-close:hover{color:#fff}

.cart-body{flex:1;overflow-y:auto;padding:.9rem 1rem;background:var(--plum)}
.cart-empty{color:var(--ink-mute);font-size:.9rem;padding:1.4rem .2rem}

/* Each line is its own small panel — the same surface the shop cards use —
   rather than rows separated by a hairline nobody can see. */
.cart-line{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:.8rem;
  align-items:center;padding:.85rem .9rem;margin-bottom:.6rem;
  background:rgba(255,255,255,.045);border:1px solid var(--line-soft);border-radius:3px}
.cart-line:last-child{margin-bottom:0}
.cart-line-t b{display:block;font-weight:600;font-size:.94rem;color:var(--ink)}
.cart-line-t em{font-style:normal;font-size:.8rem;color:var(--ink-mute)}
.cart-line-o{display:block;margin-top:.2rem;font-size:.78rem;color:var(--ink-soft)}

.cart-qty{display:flex;align-items:center;gap:.5rem}
.cart-qty button{width:1.7rem;height:1.7rem;background:var(--btn-face);
  border:1px solid var(--line-btn);color:var(--ink);cursor:pointer;border-radius:2px;line-height:1}
.cart-qty button{transition:background .2s ease,border-color .2s ease,color .2s ease}
.cart-qty button:hover{
  background:var(--accent-hot);border-color:var(--accent-hot);color:#fff;
  transition:background var(--lit) ease,border-color var(--lit) ease,color var(--lit) ease;
}
.cart-qty span{font-size:.9rem;min-width:1ch;text-align:center;color:var(--ink)}
.cart-line-p{font-size:.92rem;color:var(--accent-text);white-space:nowrap}

.cart-foot{padding:1.1rem 1.2rem calc(1.1rem + env(safe-area-inset-bottom));
  background:var(--plum-deep);border-top:1px solid var(--line)}
.cart-total{display:flex;justify-content:space-between;align-items:baseline;
  margin:0 0 .3rem;font-size:.95rem;color:var(--ink)}
.cart-total b{font-family:'Fraunces',Georgia,serif;font-size:1.3rem;color:var(--ink)}
.cart-fine{margin:0 0 1rem;font-size:.78rem;color:var(--ink-mute)}
.cart-go{width:100%;text-align:center}
.cart-go:disabled{background:transparent;border:1px solid #4a1935;color:var(--ink-faint);cursor:default}
.cart-clear{display:block;width:100%;margin-top:.7rem;background:none;border:none;
  color:var(--ink-mute);font:inherit;font-size:.8rem;cursor:pointer;padding:.35rem}
.cart-clear:hover{color:var(--accent-text)}

/* ---------- footer ------------------------------------------------------ */
.foot{padding:2rem 0 3rem;font-size:.82rem;color:#8a6178;border-top:1px solid var(--line)}
.foot .wrap{display:flex;gap:1.2rem;flex-wrap:wrap;justify-content:space-between}
.foot-links a{color:var(--ink-faint);text-decoration:none;margin-left:1rem}
.foot-links a:first-child{margin-left:0}
.foot-links a:hover{color:#fff}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width:820px){
  .hero{grid-template-columns:1fr}
  .hero-text{border-right:none;padding:2.6rem 1.4rem}
  .hero-tree{padding:1rem 1.2rem 1.6rem}
  .lessons .wrap,.mail .wrap,.ks .wrap,.bio .wrap{grid-template-columns:1fr;gap:1.3rem}
  .portrait{width:7rem}
}

@media (max-width:720px){
  .bar-nav{display:none}
  .menu-btn{display:block}
  .bar{gap:.7rem;padding:.5rem .9rem}
  .wrap{padding-left:1.2rem;padding-right:1.2rem}
  section{padding:2.5rem 0}
  section > .wrap > h2{font-size:1.6rem}
  .field{width:100%}
  .field input{min-width:0;flex:1 1 12rem}

  /* Section padding drops to 2.5rem here, so the divider offsets follow it.
     These were sitting just outside this closing brace, which meant they
     applied at every width and quietly overrode the 2.5rem above — the
     dividers never sat where they were meant to on desktop. */
  .quotes::before, .apps::before, .res::before, .ks::before, .mail::before {
    bottom: 2rem;
  }
  .quotes::after, .apps::after, .res::after, .mail::after {
    top: 2rem;
  }
}

@media (max-width:420px){
  .mark{font-size:.92rem}
  .cart-btn{padding:.42rem .65rem;font-size:.8rem}
  .menu-btn{padding:.38rem .6rem;font-size:.78rem}
  .hero h1{font-size:2.05rem}
}

/* On touch the corners are too tight, so the sheet is used instead. */
@media (hover:none){
  .tree-hint{display:none}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  /* No rotation either — the faces just swap. */
  .card-flip{transform:none!important}
  .card .face-back{transform:none;visibility:hidden}
  .card.flipped .face-front{visibility:hidden}
  .card.flipped .face-back{visibility:visible}
  .reel{scroll-behavior:auto}
}