/* ============================================================
   neoSKiN — hub index (concerns + treatments)

   The two hubs were the flattest pages in the build: a putty
   type hero on pages whose children all get pine, then 13-14
   identical cards each ending in the same word. Fourteen equal
   boxes give the eye nothing to hold, so nothing is chosen.

   This replaces the card grid with an INDEX. Hairline rows,
   type on the field, no elevation — the register of a contents
   page rather than a product listing. One plate beside the list
   carries the picture, so the page holds a single image at a
   time instead of fourteen thumbnails competing.

   Sage stays a verb: it appears only on the row you are on.
   Tokens, nav, footer and the reveal grammar come from
   base.css + chrome.css + subpages.css.
   ============================================================ */

/* ============================================================
   HERO — pine, so a top-level destination reads like one
   ============================================================ */
.ix-hero{
  background:var(--pine);color:var(--bone);
  position:relative;isolation:isolate;
  min-height:clamp(430px,66svh,700px);
  display:flex;align-items:flex-end;
  padding-block:calc(var(--nav-h) + var(--s8)) clamp(32px,5vh,56px);
}
.ix-hero::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(120% 90% at 12% 0%, rgba(163,173,146,.18), transparent 58%),
    linear-gradient(118deg, rgba(239,233,222,.03), transparent 42%, rgba(0,0,0,.16));
}
/* grain, so the pine reads as stock rather than flat fill */
.ix-hero::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.35;
  mix-blend-mode:overlay;
  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='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.4'/%3E%3C/svg%3E");
}
.ix-hero > .container{width:min(1240px,calc(100% - 48px))}
.ix-crumb{
  font-family:'JetBrains Mono',monospace;font-size:.75rem;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--sage-on-dark);margin-bottom:var(--s6);display:block;
}
.ix-crumb a{color:var(--bone-dim);text-decoration:none}
.ix-crumb a:hover{color:var(--bone)}
.ix-hero h1{
  font-size:clamp(2.6rem,6.2vw,5.2rem);line-height:1.02;
  margin:0 0 var(--s5);max-width:15ch;
  text-shadow:0 2px 30px rgba(0,0,0,.3);
}
.ix-hero .ix-lede{
  color:var(--bone-dim);max-width:40ch;font-size:var(--t-1);margin:0;
}
/* the register line: what this page contains, stated plainly */
.ix-register{
  margin-top:clamp(38px,7vh,76px);
  border-top:1px solid rgba(247,244,238,.20);
  padding-top:var(--s4);
  display:flex;flex-wrap:wrap;gap:var(--s3) clamp(20px,3.4vw,52px);
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.16em;text-transform:uppercase;color:var(--bone-dim);
}
.ix-register b{color:var(--sage-on-dark);font-weight:500}

/* ============================================================
   THE INDEX
   ============================================================ */
[id]{scroll-margin-top:calc(var(--nav-h) + 24px)}
.ix-sec{
  background:var(--bg);
  padding-block:clamp(52px,8vh,96px) clamp(64px,10vh,120px);
}
.ix-intro{
  max-width:44em;margin:0 0 clamp(30px,5vh,56px);
  color:var(--ivory-dim);font-size:var(--t-1);
}
.ix-intro p{margin:0 0 var(--s4)}
.ix-intro p:last-child{margin-bottom:0}

.ix-wrap{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,.40fr);
  gap:clamp(28px,4.5vw,72px);align-items:start;
}

/* ---- group label: a set, not a section. Small, mono, quiet ---- */
.ix-group{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:var(--s4);margin:clamp(34px,5vh,60px) 0 var(--s3);
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--sage-label);font-weight:500;
}
.ix-group:first-child{margin-top:0}
.ix-group span{color:var(--ivory-dim);font-weight:400;letter-spacing:.12em}

/* ---- the row ---- */
.ix-row{
  position:relative;display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:clamp(14px,2vw,28px);
  padding:clamp(17px,2vw,25px) 0;
  border-top:1px solid var(--hairline-2);
  color:var(--ivory);text-decoration:none;
  isolation:isolate;
}
.ix-row:last-child{border-bottom:1px solid var(--hairline-2)}
/* the sage rule draws across the top edge of the live row */
.ix-row::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;
  background:var(--champagne);transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-state) var(--ease-soft);
}
/* and the faintest wash, so the row lifts off the field without a card */
.ix-row::after{
  content:"";position:absolute;inset:-1px calc(var(--s4) * -1) -1px calc(var(--s4) * -1);
  z-index:-1;border-radius:var(--radius-sm);opacity:0;
  background:linear-gradient(90deg,rgba(124,131,112,.07),rgba(124,131,112,0) 48%);
  transition:opacity var(--dur-state) var(--ease-soft);
}
.ix-row:hover::before,.ix-row:focus-visible::before,
.ix-row.is-live::before{transform:scaleX(1)}
/* the wash belongs to the pointer, not to the plate. On load row 01 is
   live so the plate has something to show — it should not also look
   hovered, or the page opens already touched. */
.ix-row:hover::after,.ix-row:focus-visible::after{opacity:1}
.ix-row:focus-visible{outline:2px solid var(--champagne);outline-offset:6px;border-radius:4px}

.ix-mark{
  width:clamp(22px,2.2vw,28px);height:clamp(22px,2.2vw,28px);
  color:var(--ivory-dim);flex:none;
  transition:color var(--dur-state) var(--ease-soft),
             transform var(--dur-state) var(--ease-soft);
}
.ix-row:hover .ix-mark,.ix-row:focus-visible .ix-mark,
.ix-row.is-live .ix-mark{color:var(--champagne);transform:translateX(2px)}

.ix-body{min-width:0;display:block}
.ix-name{
  display:block;margin:0;font-family:'Expose',Georgia,serif;font-weight:400;
  font-size:clamp(1.28rem,2.4vw,1.95rem);line-height:1.06;
  letter-spacing:-.01em;color:var(--ivory);
  transition:transform var(--dur-state) var(--ease-soft);
}
.ix-row:hover .ix-name,.ix-row:focus-visible .ix-name,
.ix-row.is-live .ix-name{transform:translateX(6px)}
.ix-note{
  display:block;margin:7px 0 0;font-size:var(--t-s);line-height:1.5;
  color:var(--ivory-dim);max-width:48ch;
  transition:transform var(--dur-state) var(--ease-soft);
}
.ix-row:hover .ix-note,.ix-row:focus-visible .ix-note,
.ix-row.is-live .ix-note{transform:translateX(6px)}
/* the row being read firms up a shade. Not a colour change — the
   note simply stops receding. --ivory-dim is still the floor. */
.ix-row.is-live .ix-name{color:var(--ivory)}
.ix-row:hover .ix-note,.ix-row.is-live .ix-note{color:var(--ivory-dim);opacity:1}
.ix-note{opacity:.86;transition:opacity var(--dur-state) var(--ease-soft),
             transform var(--dur-state) var(--ease-soft)}

.ix-meta{
  display:flex;align-items:center;gap:clamp(10px,1.5vw,20px);
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.1em;text-transform:uppercase;
  color:var(--ivory-dim);white-space:nowrap;
}
.ix-price{color:var(--ivory)}
.ix-num{opacity:.55;font-variant-numeric:tabular-nums}
.ix-arrow{
  width:17px;height:17px;flex:none;opacity:.32;
  transition:opacity var(--dur-state) var(--ease-soft),
             transform var(--dur-state) var(--ease-soft);
}
.ix-row:hover .ix-arrow,.ix-row:focus-visible .ix-arrow,
.ix-row.is-live .ix-arrow{opacity:1;transform:translate(3px,-3px);color:var(--sage-label)}

/* ============================================================
   THE PLATE — one picture at a time, tracking the live row
   ============================================================ */
.ix-media{position:sticky;top:calc(var(--nav-h) + 20px)}
.ix-plate{
  position:relative;aspect-ratio:5/6;overflow:hidden;
  border-radius:var(--radius-card);background:var(--bg-3);
  border:1px solid var(--hairline-2);box-shadow:var(--e2);
}
.ix-shot{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.05);
  transition:opacity var(--dur-state) var(--ease-soft),
             transform var(--dur-amb) var(--ease-soft);
}
.ix-shot.is-on{opacity:1;transform:scale(1)}
.ix-plate::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,rgba(34,38,30,.72),rgba(34,38,30,.18) 34%,transparent 62%);
}
.ix-cap{
  position:absolute;left:clamp(16px,2vw,22px);right:clamp(16px,2vw,22px);
  bottom:clamp(14px,1.8vw,20px);z-index:2;color:var(--bone);
}
.ix-cap i{
  display:block;font-style:normal;
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.16em;text-transform:uppercase;color:var(--sage-on-dark);
  margin-bottom:6px;
}
.ix-cap b{
  display:block;font-family:'Expose',Georgia,serif;font-weight:400;
  font-size:clamp(1.02rem,1.5vw,1.24rem);line-height:1.15;
}
.ix-legend{
  display:flex;justify-content:space-between;gap:var(--s4);
  margin-top:var(--s4);padding-top:var(--s3);
  border-top:1px solid var(--hairline-2);
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.12em;text-transform:uppercase;color:var(--ivory-dim);
}

/* ============================================================
   CROSS BAND — the two hubs finally speak to each other
   ============================================================ */
.ix-cross{
  background:var(--pine);color:var(--bone);
  position:relative;isolation:isolate;
  padding-block:clamp(46px,7vh,88px);
}
.ix-cross::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(90% 130% at 78% 0%,rgba(163,173,146,.13),transparent 58%);
}
.ix-cross-in{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:clamp(22px,4vw,60px);flex-wrap:wrap;
}
.ix-cross i{
  display:block;font-style:normal;
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--sage-on-dark);margin-bottom:var(--s3);
}
.ix-cross h2{
  margin:0;font-size:clamp(1.6rem,3.2vw,2.5rem);line-height:1.08;max-width:18ch;
}
.ix-cross p{margin:var(--s3) 0 0;color:var(--bone-dim);max-width:40ch}
.ix-cross .btn{background:var(--glass-fill);color:var(--bone);border-color:var(--glass-edge-strong)}
.ix-cross .btn .btn-orb{color:var(--pine)}
.ix-cross-acts{display:flex;gap:var(--s3);flex-wrap:wrap;align-items:center}
.ix-cross-alt{
  color:var(--bone-dim);text-decoration:none;
  font-family:'JetBrains Mono',monospace;font-size:var(--t-label);
  letter-spacing:.12em;text-transform:uppercase;
  border-bottom:1px solid rgba(247,244,238,.3);padding-bottom:3px;
}
.ix-cross-alt:hover{color:var(--bone);border-bottom-color:var(--sage-on-dark)}

/* ============================================================
   NARROW — the plate goes, the index stays
   A thumbnail per row would put 14 images on a phone to decorate
   a list that already reads. Type carries it; the icon marks it.
   ============================================================ */
@media (max-width:1000px){
  .ix-wrap{grid-template-columns:1fr}
  .ix-media{display:none}
}
@media (max-width:640px){
  .ix-hero{min-height:auto;padding-block:calc(var(--nav-h) + var(--s7)) var(--s6)}
  .ix-hero h1{font-size:clamp(2.1rem,8.5vw,2.8rem);max-width:18ch;overflow-wrap:break-word}
  .ix-row{grid-template-columns:auto minmax(0,1fr);row-gap:var(--s2);align-items:start}
  .ix-mark{margin-top:2px}
  .ix-meta{grid-column:2;justify-content:flex-start}
  .ix-arrow{display:none}
  .ix-note{max-width:none}
}

@media (prefers-reduced-motion:reduce){
  .ix-row::before{transition:none}
  .ix-mark,.ix-name,.ix-note,.ix-arrow,.ix-shot{transition:opacity var(--dur-tap) linear;transform:none !important}
}

/* the register can carry a link (treatments: "+ upgrades") */
.ix-register a{color:var(--bone);text-decoration:none;border-bottom:1px solid rgba(247,244,238,.35);padding-bottom:2px}
.ix-register a:hover{border-bottom-color:var(--sage-on-dark)}

/* ============================================================
   THE INDEX, WITH DEPTH — 21 Aug 2026

   The list was one flat ladder: every row the same size, the same
   ink, one hairline apart. And on a phone it had no picture at all
   — .ix-media is the page's only imagery and it is display:none
   below 1000px, so the hub read as thirteen paragraphs.

   Three layers now instead of one:
     ground   the row being read lifts off the field
     ghost    its number, set large and faint behind the row
     subject  the row's own photograph, which on a phone is the
              only picture the page has

   All of it hangs off .is-live, which hub.js drives from POINTER,
   FOCUS *and* SCROLL. The scroll path is why this works on touch:
   nothing below is hover-gated, so a phone gets the same page.
   ============================================================ */

/* ---- the ladder. Dentéa's list works because the rows that are not
   being read step back. --ivory-dim is the documented reading floor,
   so the quiet rank is still a legible link, not a grey smear. ---- */
.ix-name{
  color:var(--ivory-dim);
  transition:color var(--dur-state) var(--ease-soft),
             transform var(--dur-state) var(--ease-soft);
}
.ix-row:hover .ix-name,.ix-row:focus-visible .ix-name,
.ix-row.is-live .ix-name{color:var(--ivory)}

/* ---- ghost numeral: the layer behind everything. z-index -2 puts it
   under the row's own wash (-1), so it reads as printed on the page
   rather than floating over it. ---- */
.ix-ghost{
  /* clear of .ix-meta — at right:0 the ghost sat directly under the
     small number and the arrow, and two numerals in the same spot read
     as a rendering fault rather than a layer */
  position:absolute;right:clamp(76px,7.5vw,116px);top:50%;z-index:-2;
  font-family:'Expose',Georgia,serif;font-weight:400;
  font-size:clamp(3.6rem,6.4vw,6rem);line-height:1;
  letter-spacing:-.05em;color:var(--ivory);
  font-variant-numeric:tabular-nums;
  opacity:0;transform:translate(26px,-50%);pointer-events:none;
  transition:opacity var(--dur-slow,.6s) var(--ease-soft),
             transform var(--dur-slow,.6s) var(--ease-soft);
}
.ix-row:hover .ix-ghost,.ix-row:focus-visible .ix-ghost,
.ix-row.is-live .ix-ghost{opacity:.08;transform:translate(0,-50%)}

/* ---- the wash becomes a lift: warm ground plus a low, wide shadow.
   Still gated on .ix-engaged — hub.js adds that on the first real
   pointer or scroll, so the page does not open looking touched
   (row 01 is live from load, only so the plate has something). ---- */
.ix-row::after{
  background:linear-gradient(90deg,
    rgba(247,244,238,.92),rgba(247,244,238,.5) 58%,rgba(247,244,238,0));
  box-shadow:0 22px 44px -30px rgba(33,29,24,.5);
}
.ix-engaged .ix-row.is-live::after{opacity:1}

/* ---- the photograph. Hidden on desktop, where the plate is already
   showing it full size; on tablet and phone it IS the plate. ---- */
.ix-thumb{display:none}

@media (max-width:1000px){
  .ix-row{
    grid-template-columns:auto minmax(0,1fr) auto clamp(78px,11vw,116px);
    align-items:center;
  }
  .ix-thumb{
    display:block;grid-column:4;grid-row:1 / -1;align-self:center;
    position:relative;overflow:hidden;border-radius:var(--radius-sm);
    aspect-ratio:4 / 5;background:rgba(33,29,24,.06);
  }
  .ix-thumb img{
    display:block;width:100%;height:100%;object-fit:cover;
    transform:scale(1);filter:saturate(.72) brightness(1.04);
    transition:transform var(--dur-slow,.6s) var(--ease-soft),
               filter var(--dur-slow,.6s) var(--ease-soft);
  }
  /* a cream veil holds the quiet rows back, so the read row is the
     only one at full strength — the ladder, applied to pictures */
  .ix-thumb::after{
    content:"";position:absolute;inset:0;
    background:rgba(239,233,222,.42);
    transition:opacity var(--dur-slow,.6s) var(--ease-soft);
  }
  .ix-row.is-live .ix-thumb img{transform:scale(1.06);filter:none}
  .ix-row.is-live .ix-thumb::after{opacity:0}
  .ix-ghost{display:none}   /* the thumb owns the right edge here */
}

@media (max-width:640px){
  .ix-row{grid-template-columns:auto minmax(0,1fr) clamp(72px,20vw,94px)}
  .ix-thumb{grid-column:3;align-self:start;margin-top:2px}
}

@media (prefers-reduced-motion:reduce){
  .ix-ghost,.ix-thumb img,.ix-thumb::after{transition:none}
  .ix-ghost{transform:translate(0,-50%)}
  .ix-thumb img{transform:none !important}
}

/* ============================================================
   ROWS AS OBJECTS — the lift is permanent, not a hover reward.

   The previous pass only raised the row you were reading, which
   left twelve flat rows waiting to be touched. Every row is a bone
   surface now, sitting on the putty field on --e1. The live row
   still separates, but by going FURTHER up (--e3 and 2px) rather
   than by being the only thing that exists.

   The hairlines go with it: a card does not need a rule to say
   where the next one starts, and the champagne top rule was
   drawing on an edge that is now a radius.
   ============================================================ */
.ix-list{display:flex;flex-direction:column;gap:clamp(9px,1.1vh,15px)}

.ix-row{
  background:var(--bg-2);
  border-top:0;
  border-radius:var(--radius-panel);
  box-shadow:var(--e1),var(--inner-lip);
  padding:clamp(18px,2vw,26px) clamp(18px,2.2vw,30px);
  transition:transform var(--dur-state) var(--ease-soft),
             box-shadow var(--dur-state) var(--ease-soft);
}
.ix-row:last-child{border-bottom:0}
.ix-row::before{display:none}
.ix-row:focus-visible{border-radius:var(--radius-panel);outline-offset:4px}

/* box-shadow does not crossfade cleanly, so the deeper elevation lives
   on the ::after layer and fades in behind the card instead */
.ix-row::after{
  inset:0;border-radius:inherit;background:none;
  box-shadow:var(--e3);
}
.ix-engaged .ix-row.is-live{transform:translateY(-2px)}

/* the veil over a quiet thumb should be the card it sits on, not the
   field behind it — putty here read as a grey cast on bone */
@media (max-width:1000px){
  .ix-thumb::after{background:rgba(253,251,246,.45)}
}

@media (prefers-reduced-motion:reduce){
  .ix-row{transition:none}
  .ix-engaged .ix-row.is-live{transform:none}
}

/* the card's own padding plus the thumb was squeezing the note to a
   ~22ch measure on a phone — pull the walls in, the card edge is
   already doing the work the padding used to do */
@media (max-width:640px){
  .ix-row{padding:15px 16px}
  .ix-row{gap:12px}
}
