/* =====================================================================
   Vivenndell — shared city delivery page
   Loaded by /vancouverisland/, /kelowna/, /vancouver/ and any city
   added later. Edit here once; every city gets it.
   ===================================================================== */
  :root{
    /* The homepage's own two tones -- --ink-000 and --ink-100 in
       styles.css. #0a0a0a was dead neutral and #111013 carried a faint
       violet that fought the gold; these are a shade darker and cooler,
       which is what makes a warm gold and a warm canvas read warm. Of the
       two backgrounds this is the better one, so both pages are now it. */
    --bg:#07080a; --panel:#0c0d10; --panel2:#121419;
    --ink:#efe9dc; --soft:#b3aa99; --faint:#7d766a;
    /* --ivory is the homepage's heading tone (#f5efe2 there). The body
       ink stays a shade softer; only titles, spec values and the reserve
       head take the bright one, exactly as styles.css does it. */
    --ivory:#f5efe2;
    /* The homepage's gold. Vivek: "match the city pages to the homepage" --
       so this token moves, and the 22 hardcoded rgba(184,148,91,...) in
       this file moved with it. There is now ONE gold on the site. */
    --gold:#b8945b; --gold-hi:#d6b88a; --champ:#d8c39a;
    /* Same stacks styles.css declares, so a label set in "the mono face"
       is literally the same face in both modals. */
    --mono:"JetBrains Mono",ui-monospace,"SFMono-Regular",Menlo,monospace;
    --serif:"Cormorant Garamond","EB Garamond",Garamond,"Times New Roman",serif;
    --line:rgba(184,148,91,.22);
    --line-soft:rgba(255,255,255,.08);
  }
  *{box-sizing:border-box; margin:0; padding:0;}
  html{scroll-behavior:smooth;}
  body{
    background:var(--bg); color:var(--ink);
    font-family:"Inter Tight",-apple-system,system-ui,sans-serif;
    font-weight:300; line-height:1.6; -webkit-font-smoothing:antialiased;
  }
  img{max-width:100%; display:block;}
  a{color:var(--gold); text-decoration:none;}
  .wrap{max-width:1240px; margin:0 auto; padding:0 20px;}

  /* ── Top bar ── */
  .topbar{
    display:flex; justify-content:space-between; align-items:center;
    padding:18px 0; border-bottom:1px solid var(--line-soft);
  }
  .wordmark{
    font-family:"Cormorant Garamond",serif; font-weight:500; letter-spacing:.34em;
    font-size:15px; color:var(--ink); text-transform:uppercase;
  }
  .wordmark span{color:var(--gold);}
  .topbar .home{font-size:12px; letter-spacing:.12em; text-transform:uppercase; color:var(--soft);}
  .topbar .home:hover{color:var(--gold);}

  /* ── Hero ── */
  .hero{text-align:center; padding:58px 0 34px; border-bottom:1px solid var(--line-soft);}
  .kicker{
    font-size:11px; letter-spacing:.42em; text-transform:uppercase; color:var(--gold);
    font-weight:500; margin-bottom:16px;
  }
  h1{
    font-family:"Cormorant Garamond",serif; font-weight:500; font-style:italic;
    font-size:clamp(34px, 6vw, 54px); line-height:1.08;
  }
  .hero .sub{max-width:660px; margin:18px auto 0; color:var(--soft); font-size:15.5px;}
  .hero-note{
    max-width:560px; margin:16px auto 0; color:var(--faint); font-size:12.5px; line-height:1.7;
  }
  .hero-note b{color:var(--gold); font-weight:500;}
  /* Compact Google rating — deliberately understated on this page. */
  .hero-rating{
    display:inline-flex; align-items:center; gap:10px; margin-top:16px;
    padding:9px 16px; border:1px solid var(--line-soft);
  }
  .hero-rating .stars{color:var(--gold); font-size:13px; letter-spacing:.1em;}
  .hero-rating .score{
    font-family:"Cormorant Garamond",serif; font-size:18px; color:var(--ink); line-height:1;
  }
  .hero-rating .lbl{
    font-size:10px; letter-spacing:.15em; text-transform:uppercase; color:var(--faint);
  }
  .hero-rating.linkable{cursor:pointer; transition:border-color .2s,background .2s;}
  .hero-rating.linkable:hover{border-color:var(--line); background:rgba(184,148,91,.05);}
  .hero-note .dot{
    display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--gold);
    margin-right:2px; vertical-align:middle;
  }
  .hero .sub b{color:var(--ink); font-weight:500;}

  /* ── Sticky controls ── */
  .controls{
    position:sticky; top:0; z-index:40; background:rgba(10,10,10,.94);
    backdrop-filter:blur(10px); border-bottom:1px solid var(--line-soft);
    padding:14px 0 13px;
  }
  .sizetabs{display:flex; justify-content:center; gap:0; margin-bottom:12px;}
  .sizetab{
    padding:11px 22px; font-family:inherit; font-size:12px; letter-spacing:.14em;
    text-transform:uppercase; font-weight:500; cursor:pointer;
    background:transparent; color:var(--soft); border:1px solid var(--line);
    -webkit-tap-highlight-color:transparent; transition:background .2s,color .2s; white-space:nowrap;
  }
  .sizetab + .sizetab{border-left:none;}
  .sizetab:first-child{border-radius:3px 0 0 3px;}
  .sizetab:last-child{border-radius:0 3px 3px 0;}
  .sizetab.on{background:var(--gold); color:#0d0b08; border-color:var(--gold);}
  .sizetab:not(.on):hover{color:var(--gold);}
  .sizetab .px{display:block; font-size:9.5px; letter-spacing:.1em; opacity:.75; margin-top:2px; text-transform:none;}

  .chips{display:flex; flex-wrap:wrap; justify-content:center; gap:7px;}
  .chip{
    padding:7px 14px; font-family:inherit; font-size:11px; letter-spacing:.1em;
    text-transform:uppercase; font-weight:500; cursor:pointer; border-radius:999px;
    background:transparent; color:var(--faint); border:1px solid var(--line-soft);
    -webkit-tap-highlight-color:transparent; transition:all .2s; white-space:nowrap;
  }
  .chip:hover{color:var(--gold); border-color:var(--line);}
  .chip.on{background:rgba(184,148,91,.16); color:var(--gold); border-color:var(--gold);}
  .count{text-align:center; font-size:11.5px; color:var(--faint); margin-top:11px; letter-spacing:.06em;}

  /* mobile: chips become a single swipeable row instead of a tall wrapped block,
     so the sticky bar doesn't eat a third of the screen */
  @media(max-width:760px){
    .controls{padding:11px 0 10px;}
    .chips{
      flex-wrap:nowrap; justify-content:flex-start; overflow-x:auto; gap:6px;
      scrollbar-width:none; -ms-overflow-style:none;
      margin:0 -20px; padding:2px 20px;
      -webkit-overflow-scrolling:touch;
    }
    .chips::-webkit-scrollbar{display:none;}
    .chip{flex:0 0 auto;}
    .sizetab{padding:9px 15px; font-size:11px;}
    .sizetab .px{font-size:9px;}
    .sizetabs{margin-bottom:10px;}
    .count{margin-top:9px; font-size:11px;}
  }

  /* ── Sections ── */
  .sec{padding:52px 0 0;}
  .sec.hide{display:none;}
  /* Collection grid heading only — "Gold & Japanese   4 designs" on one line.
     Scoped to .sec so it stops reaching into .isec headings, which are a
     different shape entirely. */
  .sec .sec-head{display:flex; align-items:baseline; gap:14px; margin-bottom:22px; border-bottom:1px solid var(--line-soft); padding-bottom:12px;}
  .sec .sec-head h2{
    font-family:"Cormorant Garamond",serif; font-weight:500; font-style:italic;
    font-size:clamp(23px,3.4vw,31px); line-height:1.15;
  }
  .sec .sec-head .n{font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--faint);}
  .sec .sec-head .desc{font-size:13px; color:var(--faint); margin-left:auto; text-align:right;}
  @media(max-width:700px){ .sec .sec-head{flex-wrap:wrap; gap:8px;} .sec .sec-head .desc{display:none;} }

  /* ── Grid ── */
  .grid{display:grid; grid-template-columns:repeat(2,1fr); gap:14px;}
  @media(min-width:700px){.grid{grid-template-columns:repeat(3,1fr); gap:18px;}}
  @media(min-width:1050px){.grid{grid-template-columns:repeat(4,1fr);}}
  .tile{
    position:relative; background:var(--panel); border:1px solid var(--line-soft);
    cursor:pointer; overflow:hidden; transition:border-color .25s, transform .25s;
  }
  .tile.hide{display:none;}
  .tile:hover{border-color:var(--line); transform:translateY(-2px);}
  .tile .ph{aspect-ratio:1/1; overflow:hidden; position:relative;}
  .tile .ph img{width:100%; height:100%; object-fit:cover; transition:transform .5s ease;}
  .tile:hover .ph img{transform:scale(1.04);}
  .tile .meta{padding:12px 13px 14px; display:flex; justify-content:space-between; align-items:flex-start; gap:9px;}
  .tile .meta-main{display:flex; flex-direction:column; gap:4px; min-width:0;}
  .tile .name{font-family:"Cormorant Garamond",serif; font-size:16.5px; font-weight:500; line-height:1.2;}
  .tile .prov{font-size:8.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--faint); font-weight:500;}
  .tile .prov.real{color:var(--gold);}
  /* Right-hand column of the tile caption. The price alone never told anyone
     they could buy right now — that had to be discovered by opening the piece,
     and a 50-cent click does not pay for a discovery step. The pill says it on
     the grid. */
  .tile .meta-side{display:flex; flex-direction:column; align-items:flex-end; gap:5px; flex:0 0 auto;}
  .tile .price{font-size:12.5px; color:var(--gold); letter-spacing:.04em; white-space:nowrap; font-weight:500;}
  .tile .tile-buy{
    font-size:8.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
    color:#1a1206; background:var(--gold); border-radius:3px; padding:3px 7px;
    white-space:nowrap;
  }
  .tile .zoom{
    position:absolute; bottom:9px; right:9px; padding:4px 9px;
    font-size:9px; letter-spacing:.12em; text-transform:uppercase; font-weight:500;
    background:rgba(10,10,10,.68); backdrop-filter:blur(4px); color:var(--gold);
    border:1px solid rgba(184,148,91,.4); opacity:0; transition:opacity .25s;
  }
  .tile:hover .zoom{opacity:1;}
  @media(max-width:699px){.tile .zoom{display:none;}}
  .empty{text-align:center; color:var(--faint); font-size:14px; padding:60px 0;}
  .empty.hide{display:none;}

  /* ── Order CTA ── */
  .order{
    margin-top:66px; background:var(--panel2); border:1px solid var(--line);
    padding:44px 26px; text-align:center;
  }
  @media(min-width:720px){.order{padding:54px 56px;}}
  .order h2{font-family:"Cormorant Garamond",serif; font-style:italic; font-weight:500; font-size:clamp(26px,4vw,34px);}
  .order p{color:var(--soft); font-size:15px; max-width:620px; margin:16px auto 0;}
  .order p b{color:var(--ink); font-weight:500;}
  .order .btns{margin-top:28px; display:flex; gap:13px; justify-content:center; flex-wrap:wrap;}
  .btn{
    display:inline-block; padding:14px 28px; font-size:12px; letter-spacing:.2em;
    text-transform:uppercase; font-weight:500; border:1px solid var(--gold);
    transition:background .25s,color .25s;
  }
  .btn.solid{background:var(--gold); color:#0d0b08;}
  .btn.solid:hover{background:#d8b676;}
  .btn.ghost{color:var(--gold);}
  .btn.ghost:hover{background:rgba(184,148,91,.12);}
  .order .lead{margin-top:24px; font-size:14.5px; color:var(--soft);}
  .order .lead b{color:var(--gold); font-weight:500;}
  .order .fine{margin-top:20px; font-size:12.5px; color:var(--faint); line-height:1.8;}

  /* ── Footer ── */
  footer{margin-top:66px; border-top:1px solid var(--line-soft); padding:38px 0 58px; text-align:center;}
  footer .wordmark{margin-bottom:14px; display:block;}
  footer p{color:var(--faint); font-size:13px; line-height:1.9;}
  footer .gold{color:var(--gold);}

  /* ── Lightbox ── */
  /* Centring a scrollable overlay with justify-content:center puts the overflow
     ABOVE the scroll origin, where no amount of scrolling can reach it — on a
     short screen the top of the artwork was simply cut off and unreachable.
     flex-start + auto margins on the children gives the same centring when the
     content fits, and collapses to a normal top-aligned scroll when it doesn't. */
  .lb{
    /* Opaque, not .985. That 1.5% let the grid ghost through behind the
       panel, which read as an unfinished overlay rather than a product
       page. This is also the darker of the modal's two tones. */
    position:fixed; inset:0; z-index:60; background:var(--bg);
    display:none; flex-direction:column; align-items:center; justify-content:flex-start;
    padding:20px; overflow-y:auto;
  }
  .lb.open{display:flex;}
  .lb img{max-width:100%; max-height:56vh; object-fit:contain; border:1px solid var(--line-soft);}
  /* Height, on a phone, is not what limits this image -- width is. Raising
     the cap buys no artwork and pushes the price and the button further
     down the scroll. The desktop cap is a different story and is raised. */
  @media(max-width:600px){.lb img{max-height:42vh;} .lb{padding:12px;}}

  /* two-column product modal on wide screens, stacked on mobile */
  .lb-inner{
    display:flex; flex-direction:column; align-items:center; gap:18px;
    width:100%; max-width:1800px; margin:auto;
  }
  /* Image + its view tabs as one unit. Stacked here, a full-height
     column on desktop. */
  .lb-media{display:flex; flex-direction:column; width:100%; min-width:0;}
  /* The information sits on its own slightly lighter surface, lit by two
     soft gold washes -- the homepage modal's treatment, retinted to this
     page's gold. The stage stays on --bg behind it, so the artwork is
     still the brightest thing on screen. */
  /* Left justified at every width, as the homepage panel is. A centred
     reading column gives the eye no return point: it suits one line of
     hero type and not 14.5px body copy, a price, a size row and a form.
     This was the difference Vivek spotted between the two modals. */
  .lb-panel{
    width:100%; max-width:520px; text-align:left;
    padding:26px 24px 30px;
    border:1px solid var(--line-soft); border-radius:3px;
    background:
      radial-gradient(ellipse at 80% 0%, rgba(184,148,91,.07) 0%, transparent 55%),
      radial-gradient(ellipse at 20% 100%, rgba(120,80,30,.05) 0%, transparent 50%),
      var(--panel);
  }
  /* -- Three fixed bands on a phone, as the homepage modal has --------
     Artwork and its tabs pinned at the top, purchase bar pinned at the
     bottom, and ONLY the information between them scrolls. The whole
     modal used to scroll, which carried the artwork off the screen the
     moment anyone read past the price.

     The panel also stops being a floating bordered card and fills its
     band edge to edge, so the lighter tone reads as a section of the
     page rather than a box sitting on top of one.

     The panel is a flex column so `order` works; every child keeps its
     own margins. */
  @media(max-width:1039px){
    .lb{padding:0; overflow:hidden; align-items:stretch;}
    .lb-inner{height:100%; gap:0; max-width:none; margin:0; align-items:stretch;}
    /* Edge to edge and 16:9 -- 242px at 430 wide, roughly half what this
       band used to take. Measured against the homepage modal at the same
       size, which gives its picture 275px of 932 (30%) and its
       information 457px; this page was giving the picture 474px (51%)
       and leaving only 306px of information visible above the bar.

       object-fit:cover is what makes the piece span the full width: the
       renders and photographs are SQUARE shots of a whole room, so a
       square frame spends most of itself on wall and floor. Cropping to
       the band keeps the middle, which is the artwork. `.flat` opts the
       bare artwork out -- cropping that would cut the painting. */
    .lb-media{flex:0 0 auto; padding:0; background:var(--bg);}
    /* 2:1 -- 215px at 430 wide. Another 11% off, which is what pays for
       the lock line and the card marks moving down into the pinned bar.

       NOTHING IS CROPPED. Vivek's rule: always show the whole piece, never
       zoom. The cost is visible and worth stating -- a SQUARE source shown
       whole in a band shorter than it is wide can only be as wide as the
       band is tall, so it sits 242px across with empty page either side.
       Cropping the source renders is the only thing that would make the
       artwork span the full width; CSS cannot invent the pixels. */
    .lb-stage{width:100%; aspect-ratio:2 / 1; padding:0; overflow:hidden;}
    /* Absolutely positioned, or the image's own square intrinsic size wins
       over aspect-ratio and the band stays as tall as it ever was -- which
       is exactly what happened the first time. Out of flow, it cannot push
       the stage around. */
    .lb img{
      position:absolute; inset:0;
      width:100%; height:100%; max-width:none; max-height:none;
      object-fit:contain; border:none;
      /* The thin dark gap Vivek likes on the homepage, where it is
         `.modal-artwork{padding:0.6rem}`. It has to go on the IMAGE and
         not on .lb-stage: this image is position:absolute with inset:0,
         and an absolutely positioned child resolves its insets against
         the ancestor's PADDING box, so stage padding would be ignored
         entirely. box-sizing:border-box is global, so object-fit:contain
         fits inside the padding instead of under it. */
      padding:10px;
    }
    /* 4. Flush to both edges: no padding here, and .lb-tabs drops its side
       borders and radius below, so the bar reads as one solid piece. */
    .lb .viewlabel{margin-top:0; padding:0;}
    .lb-panel{
      display:flex; flex-direction:column;
      flex:1 1 auto; min-height:0; max-width:none;
      overflow-y:auto; overscroll-behavior:contain;
      border:none; border-radius:0; border-top:1px solid var(--line-soft);
      /* No clearance to reserve any more. The purchase block is the LAST
         child and position:sticky, so it stays in flow and the scroller
         already counts its height. The measured --lb-bar padding this
         replaced, and syncBarPad() with it, existed only because the block
         used to be position:fixed and therefore invisible to layout. */
      padding:1.4rem 1.2rem 0; gap:0.9rem;
    }
    .lb-spec{margin-top:18px;}
  }
  /* -- Floor to ceiling, as the homepage modal is -------------------
     Two columns that each own their height. Only the panel scrolls, so
     the artwork stays on screen while the visitor reads and fills the
     form. Before this the whole modal was one scroll container, and
     reaching the reserve form carried the product off the page.

     grow:999 against the panel's 1 means the media column takes the free
     width first and the panel stays near its basis; once the cap stops
     the media column, the remainder flows to the panel instead of
     becoming a void. Both the ratio cap and the 999 are the homepage's.

     1.35 suits THESE images: the room renders and the real photographs
     are square (1153 and 1500px), the flat artwork is 1.78 at 42x75 and
     2.51 at 42x108. 46px is the tab bar. */
  @media(min-width:1040px){
    .lb{padding:0; overflow:hidden; align-items:stretch; justify-content:flex-start;}
    .lb-inner{
      flex-direction:row; align-items:stretch; gap:0;
      max-width:none; height:100%; margin:0;
    }
    .lb-media{flex:999 1 0; height:100%; max-width:calc((100vh - 46px) * 1.35);}
    .lb-stage{flex:1 1 auto; min-width:0; min-height:0; padding-top:14px;}
    .lb img{max-height:100%; max-width:100%;}
    .lb-panel{
      /* 420, matching .modal-info on the homepage exactly. It was 440,
         and that 20px was the last visible difference between the two
         panels -- enough to keep a two-word title on one line here
         while it wrapped there. */
      flex:1 0 420px; max-width:none; height:100%;
      overflow-y:auto; overscroll-behavior:contain;
      padding:56px 48px 0; gap:1.4rem;
      border:none; border-radius:0; border-left:1px solid var(--line-soft);
    }
    /* The tabs sit at the foot of the media column, full width, against
       the stage they control. */
    .lb .viewlabel{
      flex:0 0 auto; margin-top:0; padding:0;
      background:var(--bg);
    }
    .lb .viewlabel:empty{padding:0; border-top:none;}
  }
  /* Above 1600 the media column has usually hit its ratio cap, so the
     panel is already absorbing the remainder on its own. This only lifts
     its floor so it is not thin beside a very large picture. */
  @media(min-width:1600px){
    .lb-panel{flex:1 0 500px;}
  }
  /* The loud thing in the panel, as it is on the homepage. The old 14px
     top margin dated from when the view tabs sat above it; they are in
     the media column now and the series line is above it instead. */
  .lb-panel .name{
    margin:0;
    font-family:var(--serif); font-style:italic; font-weight:400;
    font-size:clamp(2rem, 3.5vw, 3.8rem); line-height:1.1;
    letter-spacing:.01em; color:var(--ivory);
  }
  @media(max-width:1039px){ .lb-panel .name{font-size:1.5rem;} }
  .lb-panel .sub{color:var(--soft); font-size:13px; margin-top:6px;}
  .lb-panel .sub b{color:var(--gold); font-weight:500;}
  /* Series and description. Both come from shared/pieces.js, the same copy
     the Stripe checkout page shows, so the piece tells one story from the
     tile through to the receipt. */
  /* Muted, not gold, and above the title. In gold underneath it, it was
     the brightest thing in the panel and pulled the eye off the name. */
  /* line-height:normal on every mono micro-label below, not the body's
     1.6. The homepage panel inherits `normal`, which at these sizes is
     ~2px tighter per label -- about 16px over the whole column. This is
     the difference that made the city panel read looser than the
     homepage's at identical font sizes. */
  .lb-series{
    margin:0; font-family:var(--mono); font-weight:400;
    font-size:.55rem; letter-spacing:.2em; text-transform:uppercase;
    line-height:normal;
  }
  /* Gold, which is where the homepage's leading Roman numeral went when it
     was removed. Same line in both modals now. */
  .lb-series .ser{color:var(--gold);}
  /* The homepage's eyebrow, in its three tones: the series name muted,
     the separator dimmer still, the number in gold. That gilded weight on
     "No. I" is the affectation Vivek named -- it is what makes the line
     read like the head of a certificate rather than a breadcrumb. */
  .lb-series .sep{color:rgba(184,148,91,.45); margin:0 4px;}
  .lb-series .no{color:var(--gold);}
  .lb-series:empty{display:none;}
  /* The homepage's description is 55% ivory, which is the part of its look
     that costs legibility. Keep this page's contrast and take its SPACING
     instead -- the air is what reads as refined, not the faintness. */
  .lb-desc{
    margin:0; font-size:.9rem; font-weight:400; line-height:1.75;
    color:rgba(239,231,216,.68);
  }
  .lb-desc:empty{display:none;}
  /* The price is the whole argument, so say what it covers where it is read.
     Only shown when there is something to buy. */
  /* Two short lines, the homepage's, in its weights: the fact in faint
     grey and the promise beneath it in champagne. The old pair said the
     same things in twice the words. */
  .lb-allin{
    margin-top:1rem; font-size:10.5px; font-weight:400; line-height:1.5;
    color:rgba(239,231,216,.42);
  }
  .lb-allin b{
    display:block; margin-top:5px; font-weight:400;
    color:rgba(216,195,154,.72);
  }
  /* The number, under the purchase block where the homepage keeps it. */
  .lb-ask{
    display:block; margin-top:.6rem;
    font-family:var(--mono); font-weight:400; line-height:normal;
    font-size:9.5px; letter-spacing:.17em; text-transform:uppercase;
    color:rgba(216,195,154,.55); text-decoration:none;
    transition:color .24s ease;
  }
  .lb-ask:hover{color:var(--champ);}

  /* ── Size toggle, inside the lightbox ──────────────────────────────
     Rendered only when the design exists at both sizes. 22 of 40 are
     42x75 only, so an always-on pair would show a dead button on more
     than half the catalogue. Each button carries its own price, because
     the choice being made is a price choice as much as a size one. */
  /* ── Pinned purchase bar ───────────────────────────────────────────
     Desktop: display:contents, so price/button/all-in lay out in the panel
     exactly as if this wrapper were not here -- nothing changes.
     Phones: a bar at the bottom of the lightbox that stays put while the
     visitor reads, because the CTA sat 0.89 screens down otherwise. */
  @media(min-width:1040px){
    /* No `order` at any width any more: the markup is in reading order, so
       the panel is a plain column. Round 6 put the purchase block straight
       under the size row; Vivek reversed that on seeing the homepage side
       by side -- the price belongs at the foot of the panel, sticky, which
       is what .lb-purchase does below. */
    .lb-panel{display:flex; flex-direction:column;}
    .lb-spec{margin-top:22px; padding-top:20px;}
  }
  /* ---- The purchase block, sticky to the foot of the panel -----------
     Vivek: "maybe it should be a little bit sticky too, so it kind of shows
     even if they're not scrolled all the way down. And then when they are
     scrolled all the way down, it kind of reveals itself to be a part of
     the screen." That is exactly `position:sticky; bottom:0` on the LAST
     child of a scroller: it rides the bottom edge while there is anything
     left below, then arrives at its own place at the end of the scroll.

     An earlier build made this sticky in the MIDDLE of the flow and it rode
     up over the size toggle, which is why the note here used to say "fixed,
     not sticky". As the last child there is nothing below it to cover.

     The block NEVER hides. An older version stepped aside once the reserve
     form came into view, which on a narrow screen -- where the form is in
     view the moment the modal opens -- meant the Buy button was never shown
     at all. Do not add a state that hides this. */
  .lb-purchase{
    position:sticky; bottom:0; z-index:6;
    /* Spare height in the panel collects ABOVE this, so when everything
       fits there is an "or", then air, then the price at the foot of the
       panel -- not a purchase block hanging off the bottom of the reserve
       form. In an overflowing column an auto margin resolves to 0, so the
       scrolling case is unaffected and the gap is the padding below. */
    margin-top:auto; padding:22px 0 14px;
    background:var(--panel);
    border-top:1px solid var(--line-soft);
    box-shadow:0 -10px 26px rgba(6,6,7,.78);
    /* ONLY the shadow animates. Fading background-color means that for
       300ms the block is semi-transparent and the copy underneath scrolls
       straight through it -- visible every time you leave the bottom of
       the scroll. The ground and the hairline have to be there the instant
       there is anything behind them, so they switch; the shadow is the
       part that is allowed to be graceful. */
    transition:box-shadow .26s ease;
  }
  /* DOCKED vs LANDED, which is the whole of what Vivek asked for.

     Docked, it is hovering over copy that is still scrolling underneath,
     so it has to say so: its own ground, a hairline, a shadow.

     Landed -- the scroll has reached its end, or the content never filled
     the panel at all -- it is just the foot of the page. All three come
     off and it reads as the same surface as everything above it. The
     border goes transparent rather than away, because removing it would
     move the block 1px and the transition would show the jump.

     .settled is set by syncSettled() in city-page.js. */
  .lb-purchase.settled{
    background:none;
    border-top-color:transparent;
    box-shadow:none;
  }
  /* Flush to the panel's edges, the way the band and the tab row are, so
     the foot of the modal reads as one piece rather than a card floating
     inside it. The panel's own bottom padding is 0 at both widths for the
     same reason: `bottom:0` on a sticky element resolves against the
     scrollport's PADDING box, so any bottom padding there would leave this
     hovering that far above the floor. */
  @media(max-width:1039px){
    .lb-purchase{margin-left:-1.2rem; margin-right:-1.2rem; padding:20px 1.2rem 16px;}
  }
  @media(min-width:1040px){
    /* -48 to match the panel's 48px of padding, so the ground reaches the
       panel edge. It was -38 from before the panel went to 48, which left
       10px of panel showing either side of the bar. */
    .lb-purchase{margin-left:-48px; margin-right:-48px; padding:24px 48px 30px;}
  }

  .lb-sizes{display:block; margin:0;}
  .lb-sizelab{
    display:block; margin-bottom:.55rem;
    font-family:var(--mono); font-weight:400;
    font-size:.52rem; letter-spacing:.18em; text-transform:uppercase;
    line-height:normal; color:rgba(239,231,216,.4);
  }
  .lb-sizerow{display:flex; flex-direction:column; align-items:flex-start; gap:.45rem;}
  /* A row, not a stack, and it carries the homepage's silhouette: a
     rectangle 13px tall whatever the size (the 42in side) and as wide as
     the piece is long. "The squares" Vivek named -- the shape is read
     before the numbers are. */
  .lb-size{
    flex:0 1 auto; padding:.35rem .75rem; cursor:pointer; background:transparent;
    border:1px solid rgba(184,148,91,.25); color:rgba(239,231,216,.6);
    border-radius:3px;
    font-family:var(--mono);
    font-size:.7rem; letter-spacing:.06em; font-weight:400;
    display:flex; flex-direction:row; align-items:center; gap:.55rem; line-height:1;
    -webkit-tap-highlight-color:transparent;
    transition:border-color .18s,color .18s,background .18s,box-shadow .18s,transform .1s;
  }
  .lb-size .shape{
    display:inline-block; height:13px; flex:0 0 auto;
    border:1.5px solid currentColor; border-radius:1px; opacity:.45;
    transition:opacity .18s;
  }
  .lb-size:hover .shape, .lb-size.on .shape{opacity:1;}
  /* Soft gold unselected, full gold selected. The choice being offered is a
     price choice as much as a size one, so the number has to look like money
     before it is picked, not after. Same size as the dimension beside it --
     a bigger number read as the heading of the button. */
  .lb-size .amt{letter-spacing:.04em; color:rgba(184,148,91,.7);}
  .lb-size:hover{border-color:rgba(184,148,91,.55); color:rgba(239,231,216,.9);}
  /* Presses in, like the homepage pill does. */
  .lb-size:active{transform:scale(.94);}
  .lb-size.on{
    border-color:var(--gold); color:var(--gold); background:rgba(184,148,91,.08);
    box-shadow:0 0 14px rgba(184,148,91,.18),
               inset 0 0 0 .5px rgba(184,148,91,.15);
  }
  .lb-size.on .amt{color:var(--gold);}

  /* The delivery sentence, the homepage's way: its own block under the
     availability badge, unlabelled. It is four lines of prose and it was
     wearing a two-word spec label, which made the label look like a
     heading for the rest of the panel. 10.5px and 1.75 line-height rather
     than the homepage's 9.5/1.9 -- same shape, but this is the one place
     the homepage's own setting is hard to read, and legibility is the
     thing Vivek has corrected me on more than anything else. */
  /* The homepage's exact setting, which Vivek has now asked for twice. It
     is quieter and tighter than the 10.5/1.75 that stood here -- the one
     place the homepage is harder to read. Left as his call, deliberately. */
  .lb-delivery{
    margin:0; font-family:var(--mono); font-weight:400;
    font-size:9.5px; letter-spacing:.14em; text-transform:uppercase;
    line-height:1.9; color:rgba(239,231,216,.38);
  }

  /* ── Construction + delivery ───────────────────────────────────────
     The two things someone spending $300-$800 on a wall actually asks:
     what is it made of, and how does it reach me. Neither was answered
     anywhere in this panel. */
  /* The hairline is .modal-rule, its own 1px element, on the homepage, with
     a full panel gap either side of it. Same line, drawn as a border here,
     so the padding above has to stand in for that second gap. */
  .lb-spec{
    margin:0; padding-top:1.4rem; border-top:1px solid rgba(184,148,91,.12);
    display:flex; flex-direction:column; gap:.7rem; text-align:left;
  }
  .lb-spec div{display:flex; flex-direction:column; gap:.15rem;}
  /* Muted, not gold -- the homepage sets these at 35% ivory. Gold on every
     micro-label spends the colour that should be carrying the price; what
     Vivek likes about the homepage is that it is understated. Gold is now
     kept for two things only: the price label and the edition number. */
  .lb-spec b{
    font-family:var(--mono); font-weight:500;
    font-size:.52rem; letter-spacing:.22em; text-transform:uppercase;
    line-height:normal; color:rgba(239,231,216,.35);
  }
  /* Italic serif, the way the homepage sets its FORMAT and CONSTRUCTION
     values -- it reads like a line from a certificate rather than a row
     of a product table. Bigger and brighter than the 12.5px muted sans
     it replaces, so the refinement does not cost legibility. */
  .lb-spec span{
    font-family:var(--serif); font-style:italic; font-weight:400;
    font-size:1rem; line-height:normal; color:var(--ivory);
  }

  /* ── Price ─────────────────────────────────────────────────────────
     "All in" is the whole pitch in two words: the number beside it is
     the number charged, delivered, taxed, full stop. It is big because
     on this product the price is the argument, not the objection. */
  /* Made to order, as the homepage says it: a dot and a hairline box.
     This is where "made to order" went when the subtitle under the title
     was removed. */
  .lb-avail{
    display:inline-flex; align-items:center; gap:.55rem;
    margin:0; padding:.38rem .8rem;
    border:1px solid rgba(184,148,91,.18); border-radius:2px;
    font-family:var(--mono); font-weight:400;
    font-size:9.5px; letter-spacing:.13em; text-transform:uppercase;
    line-height:normal; color:rgba(239,231,216,.58);
  }
  .lb-avail::before{
    content:""; flex:0 0 auto; width:6px; height:6px; border-radius:50%;
    background:var(--gold); opacity:.65;
  }

  /* A column, label above sum, as the homepage sets it. The label goes
     muted because the sum is now champagne and does not need a second
     gold thing beside it. */
  /* The block centres; the sum does not. Vivek, seeing it centred: "the
     all-in CAD price tag, $300 or $800, I think it does not need to be
     centered. That can be off to the left as it used to be." He is right --
     the price is a fact being stated, and a stated fact belongs on the
     margin the rest of the reading uses. The button is the thing being
     offered, and an offer is centred. */
  .lb-purchase{text-align:center;}
  .lb-price{
    margin-top:0; display:flex; flex-direction:column; gap:2px;
    align-items:flex-start; text-align:left;
  }
  .lb-price .lab{
    font-family:var(--mono); font-weight:400;
    font-size:.52rem; letter-spacing:.2em; text-transform:uppercase;
    line-height:normal; color:rgba(239,231,216,.35);
  }
  .lb-price .val{
    font-family:var(--serif); font-style:italic;
    font-size:1.7rem; line-height:1;
    color:var(--champ); font-weight:400; letter-spacing:.01em;
  }
  /* ---- The reserve form, in the homepage's clothes -------------------
     Vivek: "the reservation form on the homepage is way better. Let's
     make it look like that." Serif italic head over a tracked mono line,
     8.5px captions, inset fields on a barely-lit ground, and an OUTLINED
     pill submit -- same geometry as Buy Now, so the two read as one
     family with one of them clearly primary. */
  /* One group, exactly as .modal-reserve-form is on the homepage: the
     hairline and the top padding belong to the GROUP, and the head sits
     11px from the fields inside it. They used to be two separate panel
     children sharing the panel's 22.4px gap, which read as two unrelated
     blocks with a rule floating above one of them. */
  .lb-reserve{
    display:flex; flex-direction:column; gap:11px;
    margin-top:26px; padding-top:22px;
    border-top:1px solid rgba(184,148,91,.14);
    text-align:left;
  }
  .mrf-head{display:flex; flex-direction:column; gap:3px;}
  .mrf-title{
    font-family:var(--serif); font-style:italic; font-weight:400;
    font-size:1.15rem; line-height:1.2; color:var(--ivory);
  }
  .mrf-sub{
    font-family:var(--mono); font-weight:400;
    font-size:9px; letter-spacing:.16em; text-transform:uppercase;
    line-height:normal; color:rgba(216,195,154,.55);
  }
  .lb-alt{margin-top:16px; font-size:12.5px; color:var(--faint);}
  .lb-alt a{font-weight:500;}
  /* Inside the stage's own bottom padding. It used to hang 26px BELOW
     the stage, which now lands on the tab bar. */
  /* On a phone the picture now fills the band edge to edge, so this counter
     sits ON the artwork rather than in black padding. It carries its own
     scrim so it stays readable over any image. */
  .lb-pos{
    position:absolute; bottom:8px; left:50%; transform:translateX(-50%);
    padding:3px 10px; border-radius:999px; background:rgba(8,7,6,.6);
    font-size:10.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--soft); white-space:nowrap;
  }

  /* ---- The homepage's two transitions, ported ------------------------
     Both fire on a size switch. React gives the homepage them free: a
     changed `key` remounts the node and the keyframe runs again. The
     vanilla equivalent is in city-page.js -- remove the class, force a
     reflow, add it back. Same curve and same durations as styles.css, so
     the two modals move identically. */
  @keyframes lbPriceFadeUp{
    from{opacity:0; transform:translateY(7px);}
    to{opacity:1; transform:translateY(0);}
  }
  .lb-price .val.tick{animation:lbPriceFadeUp .3s cubic-bezier(.16,1,.3,1) both;}
  @keyframes lbImgReveal{
    from{opacity:0; transform:scale(.982);}
    to{opacity:1; transform:scale(1);}
  }
  .lb img.reveal{animation:lbImgReveal .4s cubic-bezier(.16,1,.3,1) both;}

  /* in-modal reserve form — visible from the start so it reads as quick and easy */
  /* A flex column at gap 11, exactly as .modal-reserve-form is on the
     homepage: rows, the custom-size toggle, the submit and the note all
     sit 11px apart with nothing carrying its own margin. */
  #lb-form{display:flex; flex-direction:column; gap:11px; text-align:left;}
  #lb-form.sent{display:none;}
  .hidden-field{position:absolute !important; left:-9999px;}
  /* Four separate lines on a phone -- two columns there made short,
     ragged fields. The desktop panel is 441px wide and takes the
     homepage's shape: two fields per row, two rows. Keyed to the modal's
     OWN breakpoint, so the form changes shape exactly when the modal
     does rather than at some unrelated field width. */
  /* 9px between the two fields in a row, as .mrf-row is on the homepage.
     The space BETWEEN rows is the form's own gap below, not a margin
     here -- one rule for one kind of space. */
  .ff{display:grid; gap:9px; margin-bottom:0;}
  @media(min-width:1040px){.ff.two{grid-template-columns:1fr 1fr;}}
  .ff label{display:flex; flex-direction:column; gap:4px;
    font-family:"JetBrains Mono",ui-monospace,Menlo,monospace;
    font-size:8.5px; letter-spacing:.17em;
    text-transform:uppercase; color:rgba(239,231,216,.42); font-weight:400;}
  .ff label i{font-style:normal; opacity:.6;}
  /* The label is a flex COLUMN, so a bare text node and the span beside it
     became two rows and '(optional)' dropped under 'Email'. One span
     holding both is one row again. */
  .ff label .cap{display:block; line-height:normal;}
  /* Dimmed, not restyled -- .mrf-field > span i on the homepage. It keeps
     the label's uppercase mono and tracking and simply steps back. */
  .ff label .opt{opacity:.6;}
  .ff input, .ff select{
    background:rgba(255,255,255,.03); border:1px solid rgba(184,148,91,.18);
    color:var(--ink); border-radius:3px;
    padding:9px 10px;
    font-family:"Inter Tight",-apple-system,system-ui,sans-serif;
    /* 13px at weight 400, as .mrf-field input is on the homepage. 14px at
       300 was both larger and lighter -- it made each field 2px taller and
       the typed answer weaker than the label above it. */
    font-size:13px; font-weight:400;
    transition:border-color .24s ease, background .24s ease; width:100%;
  }
  .ff input:focus, .ff select:focus{
    outline:none; border-color:rgba(216,195,154,.5);
    background:rgba(255,255,255,.055);
  }
  /* iOS shrinks a select to its content unless min-width is forced, which in a
     two-column grid leaves the city field visibly narrower than the email beside it. */
  .ff select{min-width:0; -webkit-appearance:none; appearance:none;
    background-image:linear-gradient(45deg,transparent 50%,var(--soft) 50%),
                     linear-gradient(135deg,var(--soft) 50%,transparent 50%);
    background-position:calc(100% - 15px) calc(50% + 1px), calc(100% - 10px) calc(50% + 1px);
    background-size:5px 5px, 5px 5px; background-repeat:no-repeat; padding-right:30px;}
  .ff select option, .ff select optgroup{background:var(--bg); color:var(--ink);}
  /* "Need a different size?" -- ported from .mrf-custom-toggle on the
     homepage. This is the only route a visitor has to a commission, and
     the city pages did not have it at all. */
  .mrf-custom-toggle{
    align-self:flex-start;
    background:none; border:none; padding:0; cursor:pointer;
    font-family:var(--mono); font-weight:400;
    font-size:9px; letter-spacing:.17em; text-transform:uppercase;
    line-height:normal; color:rgba(216,195,154,.55);
    transition:color .24s ease;
  }
  .mrf-custom-toggle:hover{color:var(--champ);}
  .ff-msg textarea{resize:vertical; line-height:1.45;}

  .mrf-submit{
    width:100%; margin-top:2px; padding:12px 18px;
    border-radius:999px; cursor:pointer;
    background:transparent; border:1px solid rgba(216,195,154,.38);
    color:var(--ivory);
    font-family:"JetBrains Mono",ui-monospace,Menlo,monospace;
    font-size:10px; letter-spacing:.28em; text-transform:uppercase;
    transition:background .24s ease, border-color .24s ease, color .24s ease;
  }
  .mrf-submit:hover{
    background:rgba(216,195,154,.10); border-color:var(--champ); color:var(--champ);
  }
  #lb-submit:disabled{opacity:.6; cursor:default;}
  .ff-note{font-size:10.5px; line-height:1.5; color:rgba(239,231,216,.38); margin-top:0;}
  .ff-err{font-size:12.5px; color:#e08a7a; text-align:center; margin-top:9px; display:none;}
  .ff-err.show{display:block;}

  /* success state */
  #lb-done{display:none; margin-top:18px; text-align:center;
    border:1px solid var(--line); background:rgba(184,148,91,.07); padding:24px 20px;}
  #lb-done.show{display:block;}
  #lb-done .tick{font-size:30px; color:var(--gold); line-height:1;}
  #lb-done .big{font-family:"Cormorant Garamond",serif; font-style:italic; font-size:23px; margin-top:8px;}
  #lb-done .small{font-size:13.5px; color:var(--soft); margin-top:10px; line-height:1.7;}
  #lb-done .small b{color:var(--gold); font-weight:500;}
  #lb-done .btn{margin-top:18px; cursor:pointer; font-family:inherit;}

  .lb .close{
    position:absolute; top:16px; right:16px; width:44px; height:44px; cursor:pointer;
    border:1px solid var(--line-soft); background:rgba(10,10,10,.6); color:var(--ink);
    font-size:20px; line-height:1; display:flex; align-items:center; justify-content:center; z-index:3;
  }
  .lb .close:hover{border-color:var(--gold); color:var(--gold);}
  /* 12px, not 30: the image is HEIGHT-limited in this stage, so vertical
     padding comes straight off the picture. Measured at 1280x800 the old
     30+30 cost 60px of artwork. The horizontal padding is a different
     thing -- it keeps the arrows clear of the image -- and stays. */
  .lb-stage{position:relative; display:flex; align-items:center; justify-content:center; width:100%; padding-bottom:22px;}
  .lb-nav{
    position:absolute; top:50%; transform:translateY(-50%);
    width:54px; height:54px; border-radius:50%; cursor:pointer; z-index:2;
    border:1px solid rgba(184,148,91,.6); background:rgba(12,11,9,.74); color:var(--gold);
    font-size:27px; line-height:1; padding-bottom:3px;
    display:flex; align-items:center; justify-content:center;
    box-shadow:0 4px 20px rgba(0,0,0,.55); -webkit-tap-highlight-color:transparent;
    transition:background .2s,color .2s,transform .12s;
  }
  .lb-nav:hover{background:var(--gold); color:#0d0b08;}
  .lb-nav:active{transform:translateY(-50%) scale(.92);}
  .lb-nav.prev{left:12px;} .lb-nav.next{right:12px;}
  @media(min-width:1040px){
    /* 34px, down from 72. The old pair reserved a full arrow's width on each
       side so nothing could ever overlap the picture, which cost 144px of
       image whenever the stage is width-limited — and whether it is depends
       on the shape of the window, so it is not a corner case.
       The arrows are built to sit on top of artwork: their own dark disc,
       a gold border and a drop shadow. Letting them overlap the edge by
       ~22px gives the picture the rest. */
    .lb-stage{padding-left:34px; padding-right:34px;}
    .lb-nav.prev{left:2px;} .lb-nav.next{right:2px;}
  }
  /* Shot control: only drawn when a view holds more than one image. */
  .lb-shots{
    display:flex; align-items:center; justify-content:center; gap:14px;
    margin-top:12px;
  }
  .lb-shots:empty{display:none;}
  .shot-nav{
    width:30px; height:30px; border-radius:50%; cursor:pointer;
    border:1px solid var(--line); background:transparent; color:var(--gold);
    font-size:17px; line-height:1; padding-bottom:2px;
    display:flex; align-items:center; justify-content:center;
    -webkit-tap-highlight-color:transparent; transition:background .2s,color .2s;
  }
  .shot-nav:hover{background:var(--gold); color:#0d0b08;}
  .shot-count{
    font-size:10.5px; letter-spacing:.16em; text-transform:uppercase;
    color:var(--faint); min-width:52px; text-align:center;
  }
  .lb .viewlabel{margin-top:15px; display:flex;}
  .lb .viewlabel:empty{margin-top:0;}
  /* Full width, equal shares, as the homepage's tabs are. Centred pills
     read as an afterthought beside a full-width picture. */
  .lb-tabs{
    display:flex; width:100%; overflow:hidden;
    border-top:1px solid var(--line); border-bottom:1px solid var(--line);
    border-radius:0;
  }
  /* The homepage's treatment: a dark tint behind the active tab and the
     gold carried by the TEXT. Solid gold made the loudest object on the
     screen sit directly under the artwork, which is backwards. */
  /* .modal-toggle button on the homepage, value for value: mono at .58rem,
     .22em, weight 400, 12px/16px of padding. It was 10.5px of the body sans
     at weight 500, which made the bar under the picture louder than the
     eyebrow at the top of the panel. */
  .lb-tab{
    flex:1 1 0;
    padding:.75rem 1rem;
    font-family:var(--mono); font-weight:400;
    font-size:.58rem; letter-spacing:.22em; text-transform:uppercase;
    background:transparent; color:rgba(239,231,216,.35); border:none; cursor:pointer;
    -webkit-tap-highlight-color:transparent; transition:background .2s,color .2s;
    white-space:normal; line-height:1.2;
  }
  /* "(design preview)" belongs on the tab that makes the claim, not in a
     subtitle under the title. Only the render view ever carries it: when a
     real photograph exists it REPLACES the render, so "On the wall" is
     only ever drawn for a preview. */
  /* Beside the label, not beneath it -- Vivek: "(design preview) is written
     next to On the wall". As a block it was forcing a second line and making
     the whole bar 50px against the homepage's 36. */
  .lb-tab .hint{
    display:inline; margin-left:6px;
    font-family:var(--mono); font-weight:400;
    font-size:7.5px; letter-spacing:.06em; text-transform:none;
    color:rgba(239,231,216,.3);
  }
  .lb-tab.on .hint{color:rgba(184,148,91,.62);}
  .lb-tab + .lb-tab{border-left:1px solid var(--line-soft);}
  .lb-tab:hover{color:var(--champ);}
  .lb-tab.on{background:rgba(184,148,91,.07); color:var(--gold);}

  /* ── Sticky mobile CTA ── */
  .sticky-cta{
    position:fixed; left:0; right:0; bottom:0; z-index:50;
    background:rgba(10,10,10,.93); backdrop-filter:blur(8px);
    border-top:1px solid var(--line); padding:10px 16px calc(10px + env(safe-area-inset-bottom));
    display:flex; justify-content:center;
  }
  .sticky-cta a{
    font-size:11.5px; letter-spacing:.18em; text-transform:uppercase; font-weight:500;
    color:#0d0b08; background:var(--gold); padding:12px 22px; width:100%; max-width:420px; text-align:center;
  }
  @media(min-width:820px){.sticky-cta{display:none;}}
  body{padding-bottom:64px;}
  @media(min-width:820px){body{padding-bottom:0;}}
  /* ══════════════════════════════════════════════════════════════════
     Vancouver Island campaign additions.
     Namespaced .ihero rather than reusing .hero, because the collection
     hero this page inherits is a plain text block and the two rule sets
     would fight over padding and background.
     ══════════════════════════════════════════════════════════════════ */
  .ihero{position:relative; overflow:hidden; border-bottom:1px solid var(--line);}
  .ihero .bg{
    position:absolute; inset:0;
    background:url("../Vivenndell/images/Kelowna/Real-web/signal-2026-07-22-14-39-39-962_013.jpg") center 38%/cover no-repeat;
    opacity:.38; filter:saturate(.92);
  }
  .ihero .fade{position:absolute; inset:0;
    background:linear-gradient(180deg, rgba(10,10,10,.42) 0%, rgba(10,10,10,.72) 62%, var(--bg) 100%);}
  .ihero-inner{position:relative; padding:84px 0 68px; text-align:center;}
  .ihero .dates{
    font-family:"Cormorant Garamond",serif; font-style:italic; font-size:clamp(19px,3.2vw,24px);
    color:var(--gold); margin-top:14px;
  }
  .ihero .sub{max-width:660px; margin:20px auto 0; color:var(--soft); font-size:15.5px;}
  .ihero .sub b{color:var(--ink); font-weight:500;}
  .cta-row{margin-top:34px; display:flex; gap:14px; justify-content:center; flex-wrap:wrap;}

  .facts{
    display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--line-soft);
    border:1px solid var(--line-soft); margin:46px 0 0;
  }
  .fact{background:var(--panel); padding:22px 14px; text-align:center;}
  .fact .big{font-family:"Cormorant Garamond",serif; font-size:clamp(17px,2.4vw,23px); color:var(--gold); font-style:italic;}
  .fact .small{font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--faint); margin-top:6px;}

  .isec{padding:62px 0 8px;}
  /* Full-section heading: kicker, a sentence, a paragraph, centred. A block,
     not a flex row — the unscoped rules above used to turn it into one. */
  .isec .sec-head{display:block; text-align:center; max-width:680px; margin:0 auto 38px;}
  .isec .sec-head .kicker{margin-bottom:12px;}
  .isec .sec-head h2{
    font-family:"Cormorant Garamond",serif; font-weight:500; font-style:italic;
    font-size:clamp(28px,4.6vw,40px); line-height:1.15;
    /* Overrides the nowrap the collection base sets for its two-word grid
       headings. These are sentences and must be allowed to break. */
    white-space:normal;
  }
  .isec .sec-head p{color:var(--soft); font-size:14.5px; margin-top:14px;}

  .reserve-box{background:var(--panel2); border:1px solid var(--line); padding:40px 26px; margin-top:8px;}
  @media(min-width:720px){.reserve-box{padding:52px 56px;}}
  .steps{display:grid; gap:26px; margin-top:30px;}
  @media(min-width:720px){.steps{grid-template-columns:repeat(3,1fr); gap:34px;}}
  .step .n{font-family:"Cormorant Garamond",serif; font-style:italic; font-size:30px; color:var(--gold); line-height:1;}
  .step h3{font-size:13px; letter-spacing:.18em; text-transform:uppercase; font-weight:500; margin:10px 0 8px;}
  .step p{color:var(--soft); font-size:14px;}
  .step p b{color:var(--ink); font-weight:500;}

  /* ── Artist ── */
  .artist{display:grid; gap:0; grid-template-columns:1fr; border:1px solid var(--line-soft); background:var(--panel); overflow:hidden;}
  @media(min-width:860px){ .artist{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);} }
  .artist-photo{position:relative; min-height:280px;}
  .artist-photo img{width:100%; height:100%; object-fit:cover; object-position:center 20%; display:block;}
  @media(min-width:860px){ .artist-photo img{position:absolute; inset:0;} }
  .artist-body{padding:34px 30px 36px; display:flex; flex-direction:column; gap:16px;}
  @media(max-width:600px){ .artist-body{padding:26px 22px 30px;} }
  .artist-body .kicker{margin-bottom:0;}
  .artist-body h2{font-family:"Cormorant Garamond",serif; font-weight:400; line-height:1.15; font-size:clamp(25px,4.4vw,34px); color:var(--ink);}
  .artist-body p{font-size:14.5px; line-height:1.72; color:var(--soft);}
  .artist-body p b{color:var(--ink); font-weight:500;}
  .artist-sig{margin-top:6px; padding-top:16px; border-top:1px solid var(--line-soft);}
  .artist-sig .nm{font-family:"Cormorant Garamond",serif; font-size:21px; color:var(--ink); line-height:1.2;}
  .artist-sig .rl{margin-top:4px; font-size:9.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--faint);}
  .artist-proof{display:grid; gap:14px; grid-template-columns:1fr; margin-top:14px;}
  @media(min-width:640px){ .artist-proof{grid-template-columns:1fr 1fr;} }
  .artist-proof figure{border:1px solid var(--line-soft); background:var(--panel); overflow:hidden;}
  .artist-proof img{width:100%; aspect-ratio:1/1; object-fit:cover; display:block;}
  .artist-proof figcaption{padding:13px 16px 15px; font-size:12px; line-height:1.55; color:var(--faint);}
  .artist-proof figcaption b{color:var(--soft); font-weight:500;}

  /* ── Reviews ── */
  .rating-strip{
    display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
    gap:10px 16px; margin:0 0 30px; padding:18px 20px;
    border-top:1px solid var(--line); border-bottom:1px solid var(--line);
  }
  .rating-strip .stars{color:var(--gold); font-size:19px; letter-spacing:.14em;}
  .rating-strip .score{font-family:"Cormorant Garamond",serif; font-size:27px; color:var(--ink); line-height:1;}
  .rating-strip .count{font-size:11px; letter-spacing:.18em; text-transform:uppercase; color:var(--faint);}
  .rating-strip a{font-size:11px; letter-spacing:.18em; text-transform:uppercase;}
  .rating-strip.linkable{cursor:pointer;}
  .rating-strip.linkable:hover{background:rgba(184,148,91,.05);}
  .rev-grid{display:grid; gap:16px; grid-template-columns:1fr;}
  @media(min-width:640px){ .rev-grid{grid-template-columns:1fr 1fr;} }
  @media(min-width:1040px){ .rev-grid{grid-template-columns:repeat(3,1fr);} }
  .rev{background:var(--panel); border:1px solid var(--line-soft); display:flex; flex-direction:column; overflow:hidden;}
  .rev img{width:100%; aspect-ratio:4/3; object-fit:cover; display:block;}
  .rev .body{padding:20px 20px 22px; display:flex; flex-direction:column; gap:12px; flex:1;}
  .rev .rstars{color:var(--gold); font-size:12px; letter-spacing:.1em;}
  .rev blockquote{font-family:"Cormorant Garamond",serif; font-style:italic; font-size:16.5px; line-height:1.6; color:var(--ink);}
  .rev .who{margin-top:auto; padding-top:4px;}
  .rev .who b{display:block; font-size:13.5px; color:var(--soft); font-weight:500;}
  .rev .who span{display:block; margin-top:3px; font-size:9.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--faint);}
  .rev.linkable{cursor:pointer; transition:border-color .2s, background .2s;}
  .rev.linkable:hover{border-color:var(--line); background:var(--panel2);}
  .rev .verify{margin-top:10px; font-size:9.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--gold); opacity:0; transition:opacity .2s;}
  .rev.linkable:hover .verify{opacity:1;}

  /* ── Reservation form ── */
  .res-form{margin-top:34px; border-top:1px solid var(--line-soft); padding-top:34px;}
  .res-form .form-head{text-align:center; margin-bottom:28px;}
  .res-form .form-head h3{font-family:"Cormorant Garamond",serif; font-style:italic; font-weight:500; font-size:26px;}
  .res-form .form-head p{color:var(--soft); font-size:14px; margin-top:8px;}
  .hidden-field{position:absolute !important; left:-9999px;}
  .field-row{display:grid; gap:16px;}
  @media(min-width:600px){.field-row.two{grid-template-columns:1fr 1fr;}}
  .field{display:flex; flex-direction:column; gap:7px; margin-bottom:16px;}
  .field label{font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--soft); font-weight:500;}
  .field input, .field select, .field textarea{
    background:var(--bg); border:1px solid var(--line-soft); color:var(--ink);
    padding:12px 14px; font-family:inherit; font-size:15px; font-weight:300; border-radius:2px;
    transition:border-color .2s; width:100%;
  }
  .field input:focus, .field select:focus, .field textarea:focus{outline:none; border-color:var(--gold);}
  .field textarea{resize:vertical; min-height:76px;}
  .field select{
    appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:34px;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7' fill='none' stroke='%23c9a35f' stroke-width='1.4'><path d='M1 1l4.5 4.5L10 1'/></svg>");
    background-repeat:no-repeat; background-position:right 13px center;
  }
  .opt-tag{text-transform:none; letter-spacing:0; color:var(--faint); font-weight:400;}
  .form-submit{margin-top:30px; display:flex; flex-direction:column; align-items:center; gap:12px;}
  .form-submit button{cursor:pointer; width:100%; max-width:360px; font-family:inherit;}
  .form-note{font-size:12px; color:var(--faint); text-align:center;}
  .form-alt{margin-top:30px; text-align:center; font-size:14.5px; color:var(--soft); line-height:1.8;}
  .form-alt a{font-weight:500;}

  /* ── Checkout block inside the lightbox ──
     Deliberately NOT in the page's voice. The rest of this design is editorial
     — letter-spaced small caps, hairlines, square corners — which is right for
     the art and wrong for the money. Uppercase tracked type reads as a label,
     not a control; nobody has been trained to click it. This borrows the shape
     language Amazon and Shopify have already installed in every online buyer:
     sentence case, 17px, semibold, rounded, raised, price on the face. Only
     the shape changes — the colour stays gold, so it is still Vivenndell. */
  /* The homepage's pill, exactly: champagne-to-gold at 135deg, fully
     rounded, mono small caps at .32em, and the rule-and-chevron arrow
     that slides on hover. Vivek picked this over the saturated gold
     rectangle. It is quieter; the compensation is that it is now the
     only filled object in the panel, so quiet still reads as primary. */
  .lb-buy{
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px;
    width:100%; margin:14px 0 0; padding:11px 20px 10px;
    border-radius:999px; cursor:pointer;
    background:linear-gradient(135deg, var(--champ) 0%, var(--gold-hi) 100%);
    color:#0c0d10; border:1px solid transparent;
    font-family:"JetBrains Mono",ui-monospace,Menlo,monospace;
    /* 400, not 500. Measured off the homepage: .go, .when and .sub all
       run 400 there, and at 8px the extra weight closes up the counters
       on JetBrains Mono. */
    font-weight:400; line-height:1; text-transform:uppercase;
    transition:background .24s ease, color .24s ease, transform .06s;
  }
  .lb-buy:hover{
    text-decoration:none;
    background:linear-gradient(135deg, #f5efe2 0%, var(--champ) 100%);
    color:#07080a;
  }
  /* Wraps rather than overflows: at 375px with the "between trips" copy the
     face is near the pill's inner width, and a clipped button is worse than
     a two-line one. */
  .lb-buy .face{
    display:flex; align-items:center; justify-content:center;
    flex-wrap:wrap; gap:7px 12px;
  }
  /* The verb, slightly up from 10.5px -- Vivek asked for it larger, and it
     is now sharing its line with the timing, so it needs the weight to stay
     the thing you read first. */
  .lb-buy .go{font-size:13px; letter-spacing:.28em;}
  /* On the SAME line as the verb, Vivek's call: "how long until it is on my
     wall" is part of the offer, not a footnote to it. Dark on the gradient,
     so it reads as part of the button rather than copy dropped on top. */
  .lb-buy .when{
    font-size:8.5px; letter-spacing:.13em;
    color:rgba(12,13,16,.62);
  }
  /* Second line, inside the pill. This is the one place the lock is true at
     both widths: it follows the button into the pinned bar on a phone, so
     the duplicate .lb-bar-trust block it replaced is gone. */
  .lb-buy .sub{
    display:inline-flex; align-items:center; gap:5px;
    /* .lb-panel .sub is an older rule for a different sub-line and this
       element sits inside .lb-panel, so it was inheriting 6px of margin
       on top of the pill's own 6px gap. The colour and the size were
       overridden here; the margin never was. */
    margin-top:0;
    font-size:8px; letter-spacing:.11em;
    color:rgba(12,13,16,.58);
  }
  .lb-buy .sub svg{flex:0 0 auto;}
  /* A rule with a chevron on its end, not a glyph -- fixed width, so the
     hover nudge is a transform and never a reflow. */
  .lb-buy .arrow{
    position:relative; flex:0 0 auto; width:22px; height:1px;
    background:currentColor;
  }
  .lb-buy .arrow::after{
    content:""; position:absolute; right:0; top:-3px; width:7px; height:7px;
    border-top:1px solid currentColor; border-right:1px solid currentColor;
    transform:rotate(45deg); transition:transform .24s ease;
  }
  .lb-buy:hover .arrow::after{transform:rotate(45deg) translate(3px,-3px);}
  /* Presses in. A button that does not move under the finger feels like an
     image of a button, and that hesitation is expensive at $800. */
  .lb-buy:active{transform:translateY(1px);}

  /* ---- Payment marks ------------------------------------------------
     All that is left of three separate trust wrappers. The sentence they
     carried ("secure checkout by Stripe") is inside the pill now, where it
     is true at both widths, so this is a quiet footer under the copy rather
     than a block that had to be written twice and hidden by width. One row,
     8px, same tracking at both widths. */
  .lb-cards{
    display:flex; align-items:center; justify-content:center;
    gap:5px; margin-top:.75rem; flex-wrap:wrap;
  }
  .lb-cards span{
    font-family:var(--mono); font-weight:400;
    font-size:8px; letter-spacing:.1em; line-height:normal;
    color:rgba(239,231,216,.38);
    border:1px solid rgba(184,148,91,.18); border-radius:2px; padding:3px 6px;
    background:none; white-space:nowrap;
  }
  /* Beats the display:flex above wherever it is written; the plain `hidden`
     attribute would not, because the rule above sets display explicitly. */
  .lb-cards[hidden]{display:none;}

  /* The divider that demotes the reserve. A ruled "or" reads as the other way
     round; two equal buttons read as a decision, and a decision stalls. */
  /* 26px above: the biggest seam in the panel -- everything before it is
     about buying, everything after is the free alternative. It was flush
     against the delivery line. */
  .lb-or{
    display:flex; align-items:center; gap:14px; margin:.4rem 0 0;
    font-family:var(--mono); font-weight:400;
    font-size:9px; letter-spacing:.26em; text-transform:uppercase;
    line-height:normal; color:rgba(216,195,154,.5);
  }
  .lb-or::before, .lb-or::after{
    content:""; flex:1 1 auto; height:1px; background:rgba(184,148,91,.30);
  }
  /* The purchase block sits BELOW the form now, so the old "tighten the head
     because the price is just above it" rule had nothing left to do. The
     submit is outlined whether or not there is a Buy button, so the other
     has-buy demotions went the same way. */

  /* Trip banner. Loud enough to be read before the hero makes a promise the
     calendar can no longer keep, quiet enough not to look like an error. */
  .trip-banner{
    margin:14px 0 0; padding:13px 18px; border:1px solid var(--line);
    background:rgba(184,148,91,.07); border-radius:4px;
    font-size:14px; line-height:1.6; color:var(--soft); text-align:center;
  }
  .trip-banner b{color:var(--ink); font-weight:500;}
