/* ============================================================
   CARRIAN ORO — motion & polish layer
   Loaded after main.css and pages.css.

   35  The turn        — scroll-scrubbed ring on the home page
   36  Page transitions — cross-document View Transitions
   37  Image reveals   — curtain wipe as media enters the viewport
   38  Micro-feedback  — magnetic CTAs, press states, cart fly, stagger
   39  Reading bar     — progress hairline on journal posts
   40  Buy bar         — sticky add-to-selection on mobile piece pages
   41  Texture         — fine grain on the dark grounds
   42  Reduced motion  — everything above, switched off

   Principle (from the UX guidelines): motion is scroll-LINKED, never
   scroll-jacked. Native scroll speed is untouched; the ring simply
   follows your position. One key motion per view.
   ============================================================ */


/* ---------- 35. THE TURN ------------------------------------------
   Default styles are a complete static hero: ring, headline, and the
   three chapters as a list. An inline <head> script adds html.motion
   (JS on, no reduced-motion preference) BEFORE first paint, which turns
   it into the sticky scroll stage with no layout jump. No JS / reduced
   motion = the static version.                                        */

.turn{position:relative;background:var(--obsidian);color:var(--ivory)}
.turn__stage{position:relative;isolation:isolate;overflow:hidden;
  min-height:100svh;padding:calc(var(--nav-h) + 3rem) 0 4rem;display:grid;align-items:center}

/* The ring lives on the right on desktop, feathered into the ground so
   the square frame never reads as a box. */
.turn__ring{position:absolute;z-index:0;top:50%;right:clamp(0px,3vw,5rem);
  width:min(86svh,56vw);aspect-ratio:1;translate:0 -50%;
  scale:var(--ring-scale,1);
  -webkit-mask-image:radial-gradient(ellipse 50% 50% at 50% 48%,#000 68%,transparent 100%);
          mask-image:radial-gradient(ellipse 50% 50% at 50% 48%,#000 68%,transparent 100%)}
.turn__poster,.turn__canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.turn__canvas{opacity:0;transition:opacity 600ms var(--e-out)}
.turn.has-canvas .turn__canvas{opacity:1}
.turn.has-canvas .turn__poster{opacity:0;transition:opacity 600ms var(--e-out)}

/* A warm pool of light behind the ring, so it doesn't float in a void */
.turn__stage::before{content:"";position:absolute;z-index:-1;top:50%;right:clamp(0px,3vw,5rem);
  width:min(86svh,56vw);aspect-ratio:1;translate:0 -50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(185,112,47,.16),rgba(185,112,47,.05) 55%,transparent 72%)}

.turn__copy{position:relative;z-index:2}
.turn__intro,.turn__chapters{max-width:min(34rem,46vw)}
.turn .hero__title{margin-top:var(--s3)}

.turn__chapters{list-style:none;margin:clamp(3rem,8vh,5rem) 0 0;padding:0;display:grid;gap:var(--s4)}
.turn__chapter{padding-top:var(--s3);border-top:1px solid rgba(250,246,241,.14)}
.turn__no{display:block;font-family:var(--display);font-size:.9375rem;letter-spacing:.12em;
  color:var(--copper-lit);margin-bottom:.9rem}
.turn__chapter h2{font-family:var(--display);font-weight:300;font-size:clamp(2rem,3.4vw,3.1rem);
  line-height:1.04;letter-spacing:-.02em;margin-bottom:.9rem}
.turn__chapter p{font-size:clamp(1rem,.95rem + .25vw,1.125rem);line-height:1.7;
  color:rgba(250,246,241,.74);max-width:36ch}

.turn__rail,.turn__hint{display:none}

/* ---- live: the sticky scroll stage ---- */
.motion .turn{height:320svh}
.motion .turn .turn__stage{position:sticky;top:0;height:100svh;min-height:0;padding:0}
.motion .turn .turn__copy{height:100%;display:grid;grid-template-areas:"s";align-items:center;
  padding-top:var(--nav-h)}
.motion .turn .turn__intro,
.motion .turn .turn__chapters{grid-area:s}
.motion .turn .turn__chapters{margin:0;display:grid;grid-template-areas:"c";gap:0}
.motion .turn .turn__chapter{grid-area:c;align-self:center;border-top:0;padding-top:0;
  opacity:0;visibility:hidden;will-change:opacity,transform}
.motion .turn .turn__intro{will-change:opacity,transform}

/* Progress rail, bottom-left: a hairline that fills as the ring turns */
.motion .turn .turn__rail{display:block;position:absolute;z-index:3;left:var(--gutter);bottom:2.5rem;
  width:clamp(96px,12vw,160px);height:1px;background:rgba(250,246,241,.16)}
.turn__rail i{position:absolute;inset:0;background:var(--copper-lit);
  transform-origin:left;transform:scaleX(var(--p,0))}

.motion .turn .turn__hint{display:flex;position:absolute;z-index:3;left:50%;bottom:2rem;translate:-50% 0;
  flex-direction:column;align-items:center;gap:.7rem;font-size:.625rem;letter-spacing:.28em;
  text-transform:uppercase;color:rgba(250,246,241,.56);opacity:calc(1 - var(--p,0) * 14)}
.turn__hint i{display:block;width:1px;height:42px;
  background:linear-gradient(180deg,var(--copper),transparent);animation:drip 2.6s var(--e-inout) infinite}

/* ---- mobile: ring above, words below ---- */
@media (max-width:767px){
  .turn__stage{padding:calc(var(--nav-h) + 1rem) 0 3rem;align-items:start}
  .turn__ring,.turn__stage::before{position:relative;top:auto;right:auto;translate:none;
    width:min(92vw,52svh);margin:0 auto}
  .turn__stage::before{position:absolute;top:calc(var(--nav-h) + 1rem);left:50%;translate:-50% 0}
  .turn__intro,.turn__chapters{max-width:none}
  .turn .hero__title{font-size:clamp(2.35rem,10.5vw,3rem)}
  .turn__chapter h2{font-size:clamp(1.9rem,8.4vw,2.4rem)}

  .motion .turn{height:280svh}
  .motion .turn .turn__ring{position:absolute;top:calc(var(--nav-h) + .5rem);left:50%;
    translate:-50% 0;margin:0;width:min(92vw,48svh)}
  .motion .turn .turn__stage::before{top:calc(var(--nav-h) + .5rem);width:min(92vw,48svh)}
  .motion .turn .turn__copy{align-items:end;padding-bottom:5rem}
  .motion .turn .turn__rail{bottom:2.25rem}
  .motion .turn .turn__hint{display:none}
}

/* ---- landscape phones: short viewport ---- */
@media (max-width:1000px) and (max-height:540px) and (orientation:landscape){
  .motion .turn{height:260svh}
  .turn__ring,.turn__stage::before{width:min(80svh,46vw)}
  .turn .hero__title{font-size:clamp(1.9rem,5vw,2.6rem)}
  .turn__chapter h2{font-size:clamp(1.6rem,4vw,2.1rem)}
  .turn__chapter p{font-size:.9375rem}
  .motion .turn .turn__hint{display:none}
}


/* ---------- 36. PAGE TRANSITIONS ----------------------------------
   Cross-document View Transitions (Chrome/Edge 126+, Safari 18.2+).
   Browsers without support simply navigate normally.
   Pieces carry view-transition-name: p-<slug> on both the card image
   and the piece-page image, so the photo morphs between the two.    */
@view-transition{navigation:auto}

.nav{view-transition-name:site-nav}

::view-transition-old(root){animation:vtOut 280ms cubic-bezier(.4,0,1,1) both}
::view-transition-new(root){animation:vtIn 560ms cubic-bezier(.16,1,.3,1) both}
@keyframes vtOut{to{opacity:0;transform:translateY(-10px)}}
@keyframes vtIn{from{opacity:0;transform:translateY(14px)}}

::view-transition-group(*){animation-duration:640ms;animation-timing-function:cubic-bezier(.16,1,.3,1)}
::view-transition-image-pair(site-nav){isolation:auto}
::view-transition-old(site-nav),::view-transition-new(site-nav){animation:none;mix-blend-mode:normal}


/* ---------- 37. IMAGE REVEALS -------------------------------------
   Media unveils with an upward curtain while the photo inside settles
   from a slight zoom — the way a piece is uncovered on a tray.        */
.card[data-reveal]{transform:translate3d(0,18px,0)}
.card[data-reveal].is-visible{transform:none}

.card[data-reveal] .card__media,
.post[data-reveal] .post__media,
[data-reveal] > .ethos__frame,
.piece__media[data-reveal],
.article__hero[data-reveal]{
  clip-path:inset(100% 0 0 0);
  transition:clip-path 1150ms cubic-bezier(.77,0,.18,1) var(--delay,0ms)}
.card[data-reveal].is-visible .card__media,
.post[data-reveal].is-visible .post__media,
.is-visible > .ethos__frame,
.piece__media[data-reveal].is-visible,
.article__hero[data-reveal].is-visible{clip-path:inset(0 0 0 0)}

.card[data-reveal] .card__art,
.post[data-reveal] .post__media img,
[data-reveal] > .ethos__frame img,
.piece__media[data-reveal] img,
.article__hero[data-reveal] img{
  scale:1.16;transition:scale 1600ms cubic-bezier(.16,1,.3,1) var(--delay,0ms),
                        transform 900ms var(--e-out)}
.card[data-reveal].is-visible .card__art,
.post[data-reveal].is-visible .post__media img,
.is-visible > .ethos__frame img,
.piece__media[data-reveal].is-visible img,
.article__hero[data-reveal].is-visible img{scale:1}

/* Arriving through a page transition: the transition IS the entrance, and
   the browser snapshots the new page on its first frame - before any
   reveal could fire. So everything shows immediately for that moment;
   below-the-fold reveals resume once it finishes. */
html.vt-in [data-reveal]{opacity:1!important;transform:none!important;transition:none!important}
html.vt-in [data-reveal] .card__media,html.vt-in [data-reveal] .post__media,
html.vt-in [data-reveal] > .ethos__frame,html.vt-in .piece__media[data-reveal],
html.vt-in .article__hero[data-reveal]{clip-path:none!important;transition:none!important}
html.vt-in [data-reveal] img{scale:1!important}
html.vt-in .split > span{transform:none!important;transition:none!important}

/* Filtering the grid is a same-document transition: only the cards should
   move, not the whole page. */
html.vt-filter::view-transition-old(root),
html.vt-filter::view-transition-new(root){animation:none}


/* ---------- 38. MICRO-FEEDBACK ------------------------------------ */

/* Magnetic CTAs: JS feeds --tx/--ty; `translate` composes with the
   existing :active scale instead of fighting it. */
[data-magnetic]{translate:var(--tx,0) var(--ty,0);
  transition:translate 460ms cubic-bezier(.16,1,.3,1),color var(--d-mid) var(--e-out),
             border-color var(--d-mid) var(--e-out),transform var(--d-fast) var(--e-out)}
[data-magnetic].is-pulling{transition:translate 120ms linear,color var(--d-mid) var(--e-out),
             border-color var(--d-mid) var(--e-out),transform var(--d-fast) var(--e-out)}

/* Press states everywhere something is tappable */
.icon-btn:active,.chip:active,.qty button:active,.card__add:active,.signup__go:active{scale:.94}
.icon-btn,.qty button,.signup__go{transition:background-color var(--d-mid) var(--e-out),
  color var(--d-mid) var(--e-out),scale 140ms var(--e-out)}

/* Nav bag nudges when something lands in it */
@keyframes bagNudge{0%,100%{rotate:0deg}25%{rotate:-11deg}60%{rotate:7deg}}
[data-cart-open].is-receiving svg{animation:bagNudge 520ms var(--e-out)}

/* The flying thumbnail */
.flyer{position:fixed;z-index:calc(var(--z-cursor) - 1);pointer-events:none;object-fit:cover;
  border:1px solid rgba(185,112,47,.5);box-shadow:0 18px 40px rgba(16,12,9,.35)}

/* Cart drawer: items arrive one after another */
@keyframes itemIn{from{opacity:0;transform:translateX(18px)}to{opacity:1;transform:none}}
.cartd.is-entering .cartd__body .citem{animation:itemIn 520ms var(--e-out) both;
  animation-delay:calc(140ms + var(--i,0) * 60ms)}

/* Filter chips: the active pill glides rather than snapping */
.chip[aria-pressed="true"]{box-shadow:0 6px 18px rgba(16,12,9,.14)}

/* Card name: a copper hairline draws in beneath on hover */
.card__name a{background:linear-gradient(var(--copper),var(--copper)) 0 100%/0 1px no-repeat;
  transition:background-size 520ms var(--e-out),color var(--d-mid) var(--e-out)}
.card:hover .card__name a,.card__name a:focus-visible{background-size:100% 1px}


/* ---------- 39. READING BAR --------------------------------------- */
.readbar{position:fixed;z-index:calc(var(--z-nav) + 1);top:0;left:0;right:0;height:2px;
  pointer-events:none;background:transparent}
.readbar i{display:block;height:100%;background:linear-gradient(90deg,var(--copper-deep),var(--copper-lit));
  transform-origin:left;transform:scaleX(var(--read,0))}


/* ---------- 40. BUY BAR (mobile piece pages) ---------------------- */
.buybar{display:none}
@media (max-width:767px){
  .buybar{display:flex;position:fixed;z-index:calc(var(--z-nav) - 2);left:0;right:0;bottom:0;
    align-items:center;justify-content:space-between;gap:1rem;
    padding:.75rem var(--gutter) calc(.75rem + env(safe-area-inset-bottom));
    background:rgba(250,246,241,.96);border-top:1px solid var(--rule);
    box-shadow:0 -10px 30px rgba(16,12,9,.08);
    transform:translateY(110%);transition:transform 480ms cubic-bezier(.16,1,.3,1)}
  .buybar.is-shown{transform:none}
  .buybar__info{display:grid;gap:.1rem;min-width:0}
  .buybar__info b{font-family:var(--display);font-size:1.15rem;font-weight:400;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .buybar__info span{font-size:.875rem;font-weight:500;color:var(--fg-muted)}
  .buybar .btn{flex:none;min-height:48px;padding:0 1.25rem}
  body.has-buybar .toast{bottom:calc(5.5rem + env(safe-area-inset-bottom))}
}


/* ---------- 41. TEXTURE -------------------------------------------
   A barely-there grain on the flat near-black grounds. Painted as a
   background layer beneath the content, never blended over it.      */
.cta,.signature,.footer,.phead--dark{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 .9 0 0 0 0 .8 0 0 0 .045 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}


/* ---------- 42. REDUCED MOTION ------------------------------------ */
@media (prefers-reduced-motion:reduce){
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}
  .card[data-reveal] .card__media,.post[data-reveal] .post__media,[data-reveal] > .ethos__frame,
  .piece__media[data-reveal],.article__hero[data-reveal]{clip-path:none!important}
  .card[data-reveal] .card__art,.post[data-reveal] .post__media img,[data-reveal] > .ethos__frame img,
  .piece__media[data-reveal] img,.article__hero[data-reveal] img{scale:1!important}
  [data-magnetic]{translate:none!important}
  .cartd.is-entering .cartd__body .citem{animation:none}
  .buybar{transition:none}
  [data-cart-open].is-receiving svg{animation:none}
}

/* Print: the scroll stage collapses to a plain section */
@media print{
  .motion .turn{height:auto}
  .motion .turn__stage{position:relative;height:auto}
  .motion .turn__intro,.motion .turn__chapter{opacity:1!important;visibility:visible!important;transform:none!important}
}

/* Primary button on dark grounds. The base .btn--solid is an obsidian
   fill, which vanishes on an obsidian section and leaves the primary
   action looking like a text link - weaker than the outlined secondary
   beside it. On dark grounds it inverts to ivory (18:1 contrast) and
   floods copper on hover. */
.turn .btn--solid,.cta .btn--solid,.bespoke .btn--solid,.signature .btn--solid,.phead--dark .btn--solid{
  background:var(--ivory);color:var(--obsidian);border-color:var(--ivory)}
.turn .btn--solid:hover,.cta .btn--solid:hover,.bespoke .btn--solid:hover,.signature .btn--solid:hover,
.turn .btn--solid:focus-visible,.cta .btn--solid:focus-visible,.bespoke .btn--solid:focus-visible,
.signature .btn--solid:focus-visible{color:var(--obsidian);border-color:var(--copper-lit)}
