/* =====================================================================
   The site's "new look" (shop, home and gallery pages; more to follow).
   The window + panels hero, category tiles, section titles, the white
   cards with their soft rose shadow, the New Arrivals / You May Also Like
   band, the shop's justified results grid, and button / icon details.
   Used with look.js (shared building blocks) and shop-landing.js (the
   shop page's own logic).

   Everything is scoped to .new-look (set on <html> and <body> of each page
   that uses it), so none of it can reach pages that haven't moved over.

   Page background: the existing blush pink (--blush in style.css) is kept
   on purpose -- LEAVE IT. If anyone wants to remove or replace it they
   must ask Zac first.
   ===================================================================== */

/* Type size: style.css keeps the root font size fixed on every page (it used
   to grow with the window above ~1440px), so text and spacing hold steady on
   big monitors; the photo areas below are sized from the window width (vw,
   with rem floors) so they still run wall to wall and keep growing. */

/* #svRoot is the shop's top half (hero); #svRootBottom sits after its
   search/filter bar (collection, studio cards). .lk marks any other block
   (home page sections) that uses the same pieces. */
#svRoot[hidden], #svRootBottom[hidden]{ display:none; }
/* Shop landing, before its hero is drawn: the hero's own size (.sv-b2-grid
   below; phones: the 26rem window, the gap and the 13rem panel row) in the
   band's blush with a slow sheen, so nothing below it moves when the hero
   arrives. New Arrivals, Your Favourites and the footer wait (keeping their
   place) until the hero and The Collection above them are drawn, so they
   aren't shoved down as the page fills in. Off for any other view
   (shop.html's head script). */
#svRoot.sv-hold{ display:block; height:clamp(36rem,46vw,66rem); background:var(--blush); background:linear-gradient(100deg, var(--blush) 30%, color-mix(in srgb, var(--blush-deep) 45%, var(--blush)) 50%, var(--blush) 70%) 0 0/250% 100%; animation:svSheen 1.6s ease-in-out infinite; }
html:not(.shop-landing-view) #svRoot.sv-hold{ display:none; }
html.shop-landing-view #svRoot.sv-hold ~ :is(footer, #shopLandingBottom, #shopFavourites){ visibility:hidden; }
@keyframes svSheen{ from{ background-position:100% 0; } to{ background-position:-50% 0; } }
@media(max-width:860px){ #svRoot.sv-hold{ height:calc(26rem + 0.375rem + 13rem); } }
@media (prefers-reduced-motion: reduce){ #svRoot.sv-hold{ animation:none; } }
/* The hero fades in once its photos have loaded (shop-landing.js). */
#svRoot.sv-arrive > *{ animation:svArrive .6s ease both; }
@keyframes svArrive{ from{ opacity:0; } to{ opacity:1; } }
@media (prefers-reduced-motion: reduce){ #svRoot.sv-arrive > *{ animation:none; } }
#svRoot, #svRootBottom, .lk{
  --sv-rose:#b5525c; --sv-taupe:#8a7b72;
  --sv-white:#fff; --sv-ink:#2a2420; --sv-ink-soft:#6b5f52; --sv-line:rgba(42,36,32,0.14);
  color:var(--sv-ink);
}
/* :where() keeps these resets at zero specificity so the component
   classes below (buttons, caps, badges) always win over them. */
:where(#svRoot, #svRootBottom, .lk) a{ color:inherit; text-decoration:none; }
/* Big serif headings at 600: Bodoni's hairlines all but vanish at 400 on large text. */
:where(#svRoot, #svRootBottom, .lk) :is(h1, h2, h3){ font-family:var(--font-serif); font-weight:600; }

.sv-badge{ display:inline-block; font-size:0.72rem; letter-spacing:0.16em; text-transform:uppercase; color:var(--sv-rose); border:1px solid var(--sv-rose); padding:0.3rem 0.75rem; }
.sv-btn{ display:inline-block; font-size:0.76rem; letter-spacing:0.18em; text-transform:uppercase; padding:0.875rem 1.875rem; border:1px solid var(--sv-ink); transition:background .3s ease, color .3s ease, border-color .3s ease; }
@media (hover:hover){ .sv-btn:hover{ background:var(--sv-ink); color:#fff; } }
.sv-btn.sv-solid{ background:var(--sv-ink); color:#fff; }
@media (hover:hover){ .sv-btn.sv-solid:hover{ background:transparent; color:var(--sv-ink); border-color:var(--sv-ink); } }
.sv-title{ font-family:var(--font-serif); font-style:italic; font-weight:600; font-size:clamp(1.6rem,3vw,2.3rem); text-align:center; margin:0 0 0.375rem; }
.sv-section{ padding:3.5rem 2.5rem; }
.sv-bg{ background-size:cover; background-position:center; }

/* ---------- hero: window + panels ---------- */
.sv-b2-grid{ display:grid; grid-template-columns:2fr 1fr; gap:0.375rem; height:clamp(36rem,46vw,66rem); }
.sv-b2-main{ position:relative; display:flex; align-items:flex-end; color:#fff; }
/* White words on photos that are mostly pieces on white: the shade pools in
   the bottom-left corner, right behind the words, and fades out before the
   middle, so the piece itself stays clean (a full-width shade turned the
   whole lower half grey). The button is solid white so it reads on any photo. */
.sv-b2-main::before{ content:""; position:absolute; inset:0; background:var(--sv-b2-shade); }
.sv-b2-grid{ --sv-b2-shade:radial-gradient(120% 75% at 0% 100%, rgba(36,26,22,.78) 0%, rgba(36,26,22,.5) 38%, rgba(36,26,22,.14) 66%, rgba(36,26,22,0) 85%);
  --sv-b2-side-shade:radial-gradient(130% 85% at 0% 100%, rgba(36,26,22,.78) 0%, rgba(36,26,22,.45) 40%, rgba(36,26,22,0) 78%); }
@media (max-width:860px){ .sv-b2-grid{ --sv-b2-shade:radial-gradient(170% 95% at 0% 100%, rgba(36,26,22,.8) 0%, rgba(36,26,22,.55) 40%, rgba(36,26,22,.16) 68%, rgba(36,26,22,0) 88%); } }
.sv-b2-main :is(h1, h2), .sv-b2-side h3{ text-shadow:0 1px 2px rgba(20,16,12,.4), 0 2px 24px rgba(20,16,12,.4); }
.sv-b2-main .sv-badge, .sv-b2-side small{ text-shadow:0 1px 8px rgba(20,16,12,.6); }
.sv-b2-main .sv-in{ position:relative; z-index:2; padding:3rem; display:flex; flex-direction:column; align-items:flex-start; gap:1rem; }
.sv-b2-main :is(h1, h2){ font-style:italic; font-size:clamp(2.8rem,5.5vw,5rem); line-height:1; }
.sv-b2-main .sv-badge{ color:#fff; border-color:#fff; }
.sv-b2-main .sv-btn{ background:#fff; border-color:#fff; color:var(--sv-ink); }
a.sv-b2-main:focus-visible .sv-btn{ background:var(--sv-ink); border-color:var(--sv-ink); color:#fff; }
@media (hover:hover){ .sv-b2-main .sv-btn:hover, a.sv-b2-main:hover .sv-btn{ background:var(--sv-ink); border-color:var(--sv-ink); color:#fff; } }
.sv-b2-side{ display:grid; grid-template-rows:repeat(var(--n,2),1fr); gap:0.375rem; }
.sv-b2-side a{ position:relative; display:flex; align-items:flex-end; padding:1.375rem; color:#fff; overflow:hidden; background:var(--iron); }
.sv-b2-side a::before{ content:""; position:absolute; inset:0; background:var(--sv-b2-side-shade); z-index:1; }
.sv-b2-side .sv-bg{ position:absolute; inset:0; transition:transform var(--hover-move); }
@media (hover:hover){ .sv-b2-side a:hover .sv-bg{ transform:scale(1.06); } }
.sv-b2-side div{ position:relative; z-index:2; }
.sv-b2-side h3{ font-style:italic; font-weight:500; font-size:1.6rem; }
/* shop hero from the Site Editor: no side panels, and several featured slides */
.sv-b2-grid.sv-b2-solo{ grid-template-columns:1fr; }
.sv-b2-rotating{ overflow:hidden; }
.sv-b2-rotating::before{ content:none; }
.sv-b2-slide{ position:absolute; inset:0; display:flex; align-items:flex-end; opacity:0; visibility:hidden; transition:opacity .9s ease, visibility 0s linear .9s; }
.sv-b2-slide.is-on{ opacity:1; visibility:visible; transition:opacity .9s ease; }
.sv-b2-slide::before{ content:""; position:absolute; inset:0; background:var(--sv-b2-shade); }
.sv-b2-dots{ position:absolute; right:1.5rem; bottom:1.5rem; z-index:3; display:flex; flex-wrap:wrap; justify-content:flex-end; gap:0.5rem; max-width:40%; }
/* Slide dots: the shop hero and the gallery hero. */
:is(.sv-b2-dots, .gl-hero-dots) button{ position:relative; width:0.6rem; height:0.6rem; padding:0; border-radius:50%; border:1px solid #fff; background:transparent; cursor:pointer; }
:is(.sv-b2-dots, .gl-hero-dots) button::after{ content:""; position:absolute; inset:-0.75rem; }
:is(.sv-b2-dots, .gl-hero-dots) button[aria-current]{ background:#fff; }
@media (prefers-reduced-motion: reduce){ .sv-b2-slide, .sv-b2-slide.is-on{ transition:none; } }
.sv-b2-side small{ font-size:0.74rem; letter-spacing:0.16em; text-transform:uppercase; opacity:.85; }

/* ---------- page rhythm ----------
   One value (--sv-gap) is both the space between collection tiles and the
   space from the tiles to the page edges, so the margins match the gaps.
   The search/filter bar (site.js's own #shopFilters) sits between the hero
   and the collection; it shares the same side gap and is kept slim so it
   adds no extra white space. */
body.new-look{ --sv-gap:1.125rem;
  /* Soft shadows, tinted rose (not black) so they sit naturally on the pink.
     Used only on the white cards and the New Arrivals product cards; the photo
     tiles stay flat. To switch them all off, set all three to none. */
  --sv-shadow-card:0 1.5rem 3rem -1.75rem rgba(122,59,67,0.30), 0 0.25rem 0.75rem -0.5rem rgba(122,59,67,0.12);
  --sv-shadow-item:0 1rem 1.75rem -1.25rem rgba(122,59,67,0.38);
  --sv-shadow-item-hover:0 1.5rem 2.5rem -1.25rem rgba(122,59,67,0.50); }
body.new-look .shop-filters{ padding:0.875rem var(--sv-gap) 0; }
body.new-look .sv-section{ padding:1.5rem 0 var(--sv-gap); }

/* ---------- category tiles ---------- */
.sv-mosaic{ display:grid; grid-template-columns:1.4fr 1fr 1fr; grid-auto-rows:clamp(14rem,21vw,32rem); max-width:none; margin:0; padding:0 var(--sv-gap); gap:var(--sv-gap); }
.sv-mosaic a:first-child{ grid-row:span 2; }
/* Tile: the photo, whole and uncovered, with the name and piece count set
   just beneath it on the page's own pink (most photos are pieces on white,
   where words on the picture needed a shade or a label to be read). On
   hover the photo fades into a second picture from the collection, a thin
   frame draws in, and the line under the name grows to its width.
   Nothing here uses transform: scale/translate. A browser draws a scaled
   element at its starting size, stretches it during the transition (soft),
   then redraws it sharp when the transition ends (a visible snap). So the
   photo "zoom", the frame and the lift animate real size / position
   (inset, bottom) instead, and are drawn crisp on every frame. */
.sv-tile{ position:relative; display:flex; flex-direction:column; }
.sv-tile-photo{ position:relative; flex:1 1 auto; min-height:0; overflow:hidden; background:var(--linen-deep); }
/* Hover: the second photo fades in while both ease in a little, and the
   white frame settles in -- one move on one clock (--hover-move). Only
   transform and opacity animate, which the graphics card does on its own;
   the zoom used to grow the photo's edges (top/right/bottom/left), so every
   frame re-laid-out and repainted a full-size photo: the choppiness. */
.sv-tile-photo .sv-bg{ position:absolute; inset:0; transform:scale(1); -webkit-backface-visibility:hidden; backface-visibility:hidden; transition:opacity var(--hover-move), transform var(--hover-move); }
/* 0.01, not 0: a fully transparent layer isn't painted, so the second photo
   would only start decoding on hover; this keeps it ready. */
.sv-tile-photo .sv-bg-b{ opacity:0.01; }
/* The hover photo downloads only on devices that can hover (look.js --b). */
@media (hover:hover){ .sv-tile-photo .sv-bg-b{ background-image:var(--b); } }
.sv-tile-photo::after{ content:""; position:absolute; inset:0.75rem; z-index:2; border:1px solid rgba(255,255,255,0.85); opacity:0; transform:scale(1.03); transition:opacity var(--hover-move), transform var(--hover-move); pointer-events:none; }
.sv-tile:focus-visible .sv-bg-b{ opacity:1; }
@media (hover:hover){ .sv-tile:hover .sv-bg-b{ opacity:1; } }
.sv-tile:focus-visible .sv-bg{ transform:scale(1.05); }
@media (hover:hover){ .sv-tile:hover .sv-bg{ transform:scale(1.05); } }
.sv-tile:focus-visible .sv-tile-photo::after{ opacity:1; transform:scale(1); }
@media (hover:hover){ .sv-tile:hover .sv-tile-photo::after{ opacity:1; transform:scale(1); } }
/* The layers exist before the first hover, so it doesn't start with a hitch. */
@media (hover:hover){ .sv-tile-photo .sv-bg{ will-change:transform, opacity; } }
@media (prefers-reduced-motion: reduce){ .sv-tile:is(:hover, :focus-visible) .sv-bg{ transform:none; } }
.sv-tile-cap{ display:flex; flex-direction:column; align-items:flex-start; gap:0.15rem; padding:0.7rem 0 0.1rem; color:var(--ink); text-align:left; }
.sv-tile-name{ position:relative; padding-bottom:0.4rem; font-family:var(--font-serif); font-style:italic; font-weight:500; font-size:1.6rem; line-height:1.1; }
.sv-mosaic > .sv-tile:first-child .sv-tile-name{ font-size:2.1rem; }   /* the shop's big first category tile only */
/* The name's underline: full width, clipped to a 1.5rem stub that opens to
   the whole line on hover. Clipping only repaints the line; growing its
   width (as before) re-laid-out the page on every frame of the hover. */
.sv-tile-name::after{ content:""; position:absolute; left:0; right:0; bottom:0; height:1px; background:currentColor; -webkit-clip-path:inset(0 calc(100% - 1.5rem) 0 0); clip-path:inset(0 calc(100% - 1.5rem) 0 0); transition:clip-path var(--hover-move), -webkit-clip-path var(--hover-move); }
.sv-tile:focus-visible .sv-tile-name::after{ -webkit-clip-path:inset(0); clip-path:inset(0); }
@media (hover:hover){ .sv-tile:hover .sv-tile-name::after{ -webkit-clip-path:inset(0); clip-path:inset(0); } }
.sv-tile-cap small{ font-size:0.78rem; letter-spacing:0.02em; color:var(--sv-ink-soft, var(--ink-soft)); }
.sv-tile-sale .sv-tile-cap small{ color:var(--sale-hot, #d62839); font-weight:600; }
/* "All items" (look.js) is only there to fill what would be an empty spot:
   on wider screens the mosaic's slots come in 5 + 3s, on phones in pairs. */
.sv-mosaic > .sv-tile-all{ display:none; }
@media (min-width:861px){ .sv-mosaic > .sv-tile-all:nth-child(3n+2){ display:block; } }
@media (max-width:860px){ .sv-mosaic > .sv-tile-all:nth-child(even){ display:flex; } }
/* Wider screens: the shop's category tiles keep their name on the photo,
   over a soft shade at the foot (and a pool of shadow right behind the
   words) so it reads on a pale photo; the name lifts on hover. Phones use
   the plain grid with the name below (further down). */
@media (min-width:861px){
  .sv-mosaic .sv-tile{ display:block; overflow:hidden; background:var(--linen-deep); }
  .sv-mosaic .sv-tile-photo{ position:absolute; inset:0; }
  .sv-mosaic .sv-tile-photo::before{ content:""; position:absolute; inset:0; z-index:1; background:linear-gradient(to top, rgba(36,26,22,0.5) 0%, rgba(36,26,22,0.2) 30%, rgba(36,26,22,0) 55%); pointer-events:none; }
  .sv-mosaic .sv-tile-cap{ position:absolute; z-index:3; left:0; right:0; bottom:0; align-items:center; gap:0.25rem; padding:1.25rem 1rem 1.5rem; text-align:center; color:#fff; isolation:isolate; transition:transform var(--hover-move); }
  .sv-mosaic .sv-tile:focus-visible .sv-tile-cap{ transform:translateY(-0.25rem); }
  @media (hover:hover){ .sv-mosaic .sv-tile:hover .sv-tile-cap{ transform:translateY(-0.25rem); } }
  .sv-mosaic .sv-tile-cap::before{ content:""; position:absolute; left:50%; top:50%; z-index:-1; width:min(100%, 22rem); height:140%; transform:translate(-50%,-50%); background:radial-gradient(ellipse at center, rgba(36,26,22,0.52) 0%, rgba(36,26,22,0.3) 40%, rgba(36,26,22,0) 72%); pointer-events:none; }
  .sv-mosaic .sv-tile-name{ padding-bottom:0.55rem; text-shadow:0 1px 3px rgba(20,16,12,0.55), 0 2px 18px rgba(20,16,12,0.5); }
  .sv-mosaic .sv-tile-name::after{ background:#fff; -webkit-clip-path:inset(0 calc(50% - 0.75rem)); clip-path:inset(0 calc(50% - 0.75rem)); }
  .sv-mosaic .sv-tile-cap small, .sv-mosaic .sv-tile-sale .sv-tile-cap small{ font-size:0.82rem; font-weight:400; color:#fff; text-shadow:0 1px 3px rgba(20,16,12,0.5), 0 1px 12px rgba(20,16,12,0.45); }
}

/* ---------- section titles ----------
   One title style for every section heading: italic, with a thin line
   either side. Used by The Collection, From our studio, New Arrivals and
   Your Favourites. */
.sv-divider{ display:flex; flex-direction:column; align-items:center; text-align:center; padding:1.5rem var(--sv-gap, 1.125rem) 1.75rem; }
/* The postcard: a band of the Upholstery page's pale cream, edge to edge,
   laid on top of the pink -- a soft shadow above and below -- with the
   cream box's gilt edges (style.css). Used by the shop's "From
   our studio" (.sv-studio) and the home page's Upholstery & Custom Painting
   (#craft). */
.sv-postcard{ position:relative; z-index:1; background:#fbf7f0;
  box-shadow:0 1.75rem 2.75rem -1.75rem rgba(42,36,32,0.42), 0 -1.25rem 2.25rem -1.75rem rgba(42,36,32,0.28); }
.sv-postcard :is(.sv-divider h2, .hm-title)::before, .sv-postcard :is(.sv-divider h2, .hm-title)::after{ background:rgba(176,141,87,0.5); }
/* "From our studio": the divider and the upholstery card on the postcard. */
.sv-studio{ padding:1.5rem 0 clamp(2rem, 4vw, 3.5rem); margin:1rem 0 3.5rem; }
.sv-studio .sv-service{ margin-bottom:0; }   /* the cream runs on under the photo */
/* Home: Upholstery & Custom Painting, the whole section on the postcard. */
body.new-look #craft.sv-postcard{ margin:3.5rem 0; padding:0.5rem 0 clamp(2rem, 4vw, 3.5rem); }
.sv-divider h2,
body.new-look .sv-title,
body.new-look .hm-title,
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-heading{ display:flex; align-items:center; gap:1.5rem; width:min(100%,44rem); margin-inline:auto; font-style:italic; font-size:clamp(1.6rem,3vw,2.3rem); }
.sv-divider h2::before, .sv-divider h2::after,
body.new-look .sv-title::before, body.new-look .sv-title::after,
body.new-look .hm-title::before, body.new-look .hm-title::after,
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-heading::before,
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-heading::after{ content:""; flex:1; height:1px; background:rgba(42,36,32,0.28); }

/* ---------- "From our studio": Upholstery & Custom Painting ----------
   The home page's photo-section treatment (no white): a wall-to-wall photo
   with the words on the same frosted-glass panel (see .hm-card-copy below). */
.sv-service{ position:relative; isolation:isolate; overflow:hidden; display:flex; align-items:center;
  min-height:clamp(26rem,36vw,52rem); margin:0 0 var(--sv-gap, 1.125rem); padding:clamp(2.5rem,5vw,6rem) 6vw; background:var(--linen-deep); }

/* Upholstery & Custom Painting: one photo, the panel on the right */
.sv-service{ justify-content:flex-end; }
.sv-service-photo{ position:absolute; inset:0; z-index:-1; display:block; overflow:hidden; }
.sv-service-photo .sv-bg{ position:absolute; inset:0; transition:transform var(--hover-move); }
@media (hover:hover){ .sv-service-photo:hover .sv-bg{ transform:scale(1.04); } }
.sv-service-copy{ display:flex; flex-direction:column; justify-content:center; }
.sv-service-copy h2{ font-size:clamp(1.9rem,3vw,2.8rem); line-height:1.05; }
.sv-service-copy h2::after{ content:""; display:block; width:3.375rem; height:1px; margin:1.25rem 0; background:var(--blush-deep); }
.sv-service-copy p{ font-size:1.05rem; line-height:1.6; color:#4a3a37; margin:0 0 1.5rem; max-width:30rem; }
.sv-service-links{ display:flex; flex-wrap:wrap; align-items:center; gap:1rem 1.75rem; }

/* ---------- New Arrivals (and Your Favourites) in the same language ----------
   These two are site.js's own sections, so this only restyles them: a
   centred italic title like "The Collection" (no eyebrow, no rule), flat
   page pink instead of the gradient band, and uniform square-cornered
   cards with the same gap between them as the page margin. Scoped to
   the two landing sections so product pages and results are untouched.

   New Arrivals: the band behind the cards. It starts just under the title
   and ends just under the cards, in a deeper rose than the page, with a
   fade at the top (--sv-fade-top, long) and bottom (--sv-fade-bottom) so it
   reads as its own boxed section that dissolves into the lighter page
   pink. Only the rail's own area is tinted; the footer below stays on the
   page pink. */
body.new-look #shopLandingBottom{ --sv-fade-top:9.5rem; --sv-fade-bottom:9rem; }
/* "You May Also Like" (product page) used to share this band. It sits right
   above the footer, where the page's own rose fade (site.js initDeepBottom)
   already deepens, and the two gradients stacked read as a smudge; it now
   sits on the plain page pink and only the footer fade remains (2026-10-13). */
body.new-look .related-pieces .h-scroll-wrap{ background:none; }
body.new-look #freshFindsTrack{ will-change:transform; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-band{ position:relative; z-index:1; padding:0 var(--sv-gap) 1.25rem; text-align:center; }
body.new-look .related-pieces .ribbon-band{ position:relative; z-index:1; padding-bottom:1.25rem; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-inner{ max-width:none; margin:0 auto; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-inner .eyebrow{ display:none; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .ribbon-band.section-head::after{ display:none; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-wrap{ background:none; padding:0 var(--sv-gap) 3.5rem; }
/* The band reaches up behind the title: the long top fade (--sv-fade-top)
   starts above the title text and the title sits on it (the heading is
   z-index 1 so it stays on top). margin-top is set so the cards land the
   same distance below the title, and margin-bottom keeps the footer the same
   distance below the cards, whatever the fade lengths. Fades use a
   smootherstep S-curve (slow, quick, slow) rather than a straight line, so
   neither end shows a hard edge. The plain linear gradient first is the
   fallback for browsers without color-mix(). */
body.new-look #shopLandingBottom, body.new-look .hm-band{
  --sv-band:#e9b9ba;
  --sv-band-flat:linear-gradient(180deg, var(--blush) 0, var(--sv-band) var(--sv-fade-top), var(--sv-band) calc(100% - var(--sv-fade-bottom)), var(--blush) 100%);
  --sv-band-bg:linear-gradient(180deg,
    var(--blush) 0,
    color-mix(in srgb, var(--sv-band) 6%, var(--blush)) calc(var(--sv-fade-top) * 0.2),
    color-mix(in srgb, var(--sv-band) 32%, var(--blush)) calc(var(--sv-fade-top) * 0.4),
    color-mix(in srgb, var(--sv-band) 68%, var(--blush)) calc(var(--sv-fade-top) * 0.6),
    color-mix(in srgb, var(--sv-band) 94%, var(--blush)) calc(var(--sv-fade-top) * 0.8),
    var(--sv-band) var(--sv-fade-top),
    var(--sv-band) calc(100% - var(--sv-fade-bottom)),
    color-mix(in srgb, var(--sv-band) 94%, var(--blush)) calc(100% - var(--sv-fade-bottom) * 0.8),
    color-mix(in srgb, var(--sv-band) 68%, var(--blush)) calc(100% - var(--sv-fade-bottom) * 0.6),
    color-mix(in srgb, var(--sv-band) 32%, var(--blush)) calc(100% - var(--sv-fade-bottom) * 0.4),
    color-mix(in srgb, var(--sv-band) 6%, var(--blush)) calc(100% - var(--sv-fade-bottom) * 0.2),
    var(--blush) 100%); }
body.new-look #shopLandingBottom .h-scroll-wrap{ margin-top:calc(3.25rem - var(--sv-fade-top)); margin-bottom:calc(4.5rem - var(--sv-fade-bottom)); padding-top:calc(var(--sv-fade-top) + 0.5rem); padding-bottom:calc(var(--sv-fade-bottom) + 0.25rem);
  background:var(--sv-band-flat); }
@supports (background:color-mix(in srgb, red 50%, blue)){
  body.new-look #shopLandingBottom .h-scroll-wrap{ background:var(--sv-band-bg); }
}
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-track{ gap:var(--sv-gap); }
/* The rails scroll by drag, swipe or trackpad; a scrollbar under them only
   breaks the page's flow (New Arrivals, Your Favourites, You May Also Like). */
body.new-look :is(#shopLandingBottom, #shopFavourites, .related-pieces) .h-scroll-wrap{ scrollbar-width:none; }
body.new-look :is(#shopLandingBottom, #shopFavourites, .related-pieces) .h-scroll-wrap::-webkit-scrollbar{ display:none; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-track .gallery-card{ width:clamp(11rem,15vw,26rem); }
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-wrap .h-scroll-track .gallery-card .g-frame{ display:block; width:100%; height:auto; aspect-ratio:3/4; border-radius:0; box-shadow:var(--sv-shadow-item); }
@media (hover:hover){
  body.new-look :is(#shopLandingBottom, #shopFavourites) .gallery-card:hover .g-frame{ box-shadow:var(--sv-shadow-item-hover); }
}
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-track .gallery-card .g-img{ width:100%; height:100%; object-fit:cover; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-track .gallery-card .g-img.no-img{ aspect-ratio:auto; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-track .g-body{ max-width:none; padding-top:0.625rem; text-align:center; }
body.new-look :is(#shopLandingBottom, #shopFavourites) .g-body h4{ font-style:italic; font-weight:500; font-size:1rem; }

/* ---------- shop items (results grid) ----------
   Justified rows: every card knows its photo's shape (--r, width / height,
   set by shop-landing.js once the photo has loaded) and grows in proportion
   to it, so all the photos in a row scale together and the row fills the
   page width exactly, with the normal gap between cards. A card won't grow
   past --row-max tall, so a row with only a few pieces isn't blown up; any
   space still left over is spread between the cards. The last row keeps its
   natural size and sits left (the ::after soaks up that row's spare room), so
   a short last row is not stretched across the page. Phones use their own
   two-column grid, so this is for wider screens only. Same soft rose shadow
   as New Arrivals. */
@media(min-width:641px){
  body.new-look #shopGrid.gallery-grid{ --row-h:16rem; --row-max:24rem; justify-content:space-between; }
  body.new-look #shopGrid .gallery-card{ --r:1.3333; flex:var(--r) 1 calc(var(--r) * var(--row-h)); min-width:0; max-width:calc(var(--r) * var(--row-max)); }
  body.new-look #shopGrid .gallery-card .g-frame{ display:block; width:100%; height:auto; aspect-ratio:var(--r); }
  body.new-look #shopGrid .gallery-card .g-img{ width:100%; height:100%; object-fit:cover; }
  body.new-look #shopGrid .gallery-card .g-img.no-img{ aspect-ratio:auto; }
  body.new-look #shopGrid.gallery-grid::after{ content:""; flex:1000 1 0; min-width:0; }
  /* Set by shop-landing.js when the last row already nearly fills the width
     (or is the only row): let it justify like the others. */
  body.new-look #shopGrid.gallery-grid.sv-fill-last::after{ display:none; }
}
/* A new set of results waits for its first photos to load (shop-landing.js
   holdForPhotos), with the footer, then fades in already in its final rows. */
body.new-look #shopGrid.gallery-grid{ transition:opacity .35s ease; }
body.new-look #shopGrid.gallery-grid.sv-wait{ opacity:0; transition:none; }
body.new-look:has(#shopGrid.sv-wait) > footer{ visibility:hidden; }
@media (prefers-reduced-motion: reduce){ body.new-look #shopGrid.gallery-grid{ transition:none; } }
body.new-look #shopGrid .gallery-card .g-frame{ box-shadow:var(--sv-shadow-item); }
@media (hover:hover){
  body.new-look #shopGrid .gallery-card:hover .g-frame{ box-shadow:var(--sv-shadow-item-hover); }
}

/* ---------- home page ----------
   The home page's sections in the same language as the shop: centred italic
   titles with a thin line either side (no small labels above them), white
   cards with the soft rose shadow, photos and tiles sharing the page gap.
   The French-door hero at the top is unchanged. Everything the dashboard's
   Site Editor can change keeps its place (see loadHomeContent in site.js);
   the small "eyebrow" labels and the shop section's paragraph are kept in
   the page for the editor but not shown, to stay minimal. */
body.new-look .hm-head{ padding:3.5rem var(--sv-gap) 1.75rem; text-align:center; }
body.new-look .hm-head .eyebrow, body.new-look #shop .hm-sub{ display:none; }
body.new-look .hm-title a{ color:inherit; text-decoration:none; }
@media (hover:hover){ body.new-look .hm-title a:hover{ color:var(--sv-rose); } }
body.new-look .hm-intro, body.new-look .hm-founder{ padding:0; }
body.new-look .hm-founder{ margin-top:3.5rem; }
body.new-look .hm-section{ padding-bottom:0.5rem; scroll-margin-top:3rem; }
body.new-look #shop #homeHero{ margin-bottom:0; }
/* Home's photo sections (intro, owner quote, upholstery, visit): no coloured
   block at all. Each is one wall-to-wall photo (the map, for Visit) with the
   words on a frosted-glass panel floating over it -- a soft blush tint plus a
   strong blur, so whatever is behind stays quiet and the text stays easy to
   read. Panels alternate sides down the page (upholstery on the left, owner
   quote and visit on the right). The intro is the exception: its words sit
   in a card under the photo at every size. Section height follows the
   window width so the photos keep their share at any zoom; on phones the
   panel sits at the foot of the photo, full width. --gold is used by the
   About page. */
body.new-look{ --gold:#b08d57; }
body.new-look .hm-card{ position:relative; isolation:isolate; overflow:hidden; display:flex; align-items:center; justify-content:flex-start;
  min-height:clamp(30rem,42vw,60rem); margin:0; padding:clamp(2.5rem,5vw,6rem) 6vw; border:0; box-shadow:none; background:var(--linen-deep); }
body.new-look .hm-card > :is(.hm-card-photo, .hm-map){ position:absolute; inset:0; z-index:-1; min-height:0; }
body.new-look .hm-card > .hm-card-copy, .sv-service-copy{ position:relative; width:min(100%, 34rem); padding:clamp(2rem,3.2vw,3.5rem);
  background:rgba(250,236,233,0.7); -webkit-backdrop-filter:blur(1.25rem) saturate(1.2); backdrop-filter:blur(1.25rem) saturate(1.2);
  border:1px solid rgba(255,255,255,0.6); box-shadow:0 1.75rem 3.5rem -1.75rem rgba(42,36,32,0.4); }
body.new-look :is(#founder, #visit) .hm-card{ justify-content:flex-end; }
/* The owner's quote is a short line: a shorter card, so the page keeps
   moving toward the shop. */
body.new-look #founder .hm-card{ min-height:clamp(20rem,26vw,36rem); padding-block:clamp(2rem,3vw,3.5rem); }
body.new-look .hm-intro-photo{ background-position:50% 42%; }
/* The intro on desktop works like phones and tablets (see the 860px block
   below): the storefront photo across the top, whole and uncovered, and
   the words in their own card under it, centred. The user preferred that
   to the panel floating over a blurred copy of the photo (2026-10-22). The
   photo is the Site Editor's (4:3 now), cropped to a band framed on the
   door and the window logo. */
@media(min-width:861px){
  body.new-look .hm-intro .hm-card{ flex-direction:column; align-items:stretch; justify-content:flex-start; min-height:0; padding:0 0 1rem; background:none; overflow:visible; }
  body.new-look .hm-intro .hm-card > .hm-card-photo{ order:-1; position:relative; inset:auto; z-index:0; height:clamp(24rem, 40vw, 40rem); background-position:50% 45%; }
  body.new-look .hm-intro .hm-card > .hm-card-copy{ z-index:1; width:min(100% - 2rem, 46rem); margin:2.5rem auto 0; align-items:center; text-align:center; }
  body.new-look .hm-intro .hm-intro-text{ margin-inline:auto; max-width:36rem; }
}
/* Visit: the pin sits mid-map, so the panel always ends short of the middle. */
body.new-look .hm-visit .hm-card > .hm-card-copy{ width:min(100%, 34rem, 40vw); }
/* The photo strip under the upholstery section keeps the page gap above it. */
body.new-look .hm-card + .hm-strip{ margin-top:var(--sv-gap); }
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  body.new-look .hm-card > .hm-card-copy, .sv-service-copy{ background:rgba(250,236,233,0.94); }
}

/* A white card: photo on one side, copy on the other */
.hm-card{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); align-items:stretch; background:var(--sv-white); border:1px solid var(--sv-line); box-shadow:var(--sv-shadow-card); margin:0 var(--sv-gap) var(--sv-gap); }
.hm-card-photo{ position:relative; display:block; min-height:clamp(22rem,25vw,40rem); background-color:var(--linen-deep); background-size:cover; background-position:center; }
.hm-card-copy{ display:flex; flex-direction:column; align-items:flex-start; justify-content:center; padding:3rem 6%; }
.hm-intro-heading{ font-style:italic; font-size:clamp(1.9rem,3vw,2.8rem); line-height:1.1; margin-bottom:1.25rem; }
.hm-intro-text, .hm-card-copy .hm-sub{ font-size:1.05rem; line-height:1.6; color:#4a3a37; margin:0 0 1.5rem; max-width:30rem; }
.hm-founder-copy{ color:inherit; transition:color .25s ease; }
.hm-founder-copy .eyebrow{ display:none; }
.hm-founder-copy blockquote{ font-family:var(--font-serif); font-style:italic; font-weight:600; font-size:clamp(1.5rem,2.6vw,2.3rem); line-height:1.25; margin-bottom:1.25rem; max-width:28rem; }
.hm-founder-name{ font-size:0.76rem; font-weight:600; letter-spacing:0.18em; text-transform:uppercase; color:var(--sv-ink-soft); padding-bottom:0.2rem; background-image:linear-gradient(currentColor,currentColor); background-repeat:no-repeat; background-position:0 100%; background-size:0% 1px; transition:background-size .4s var(--ease-out); }
@media (hover:hover){ .hm-founder-copy:hover .hm-founder-name{ background-size:100% 1px; } }

/* A row of photo tiles (the craft photos, Instagram). Same tile as the shop's
   category tiles, so the hover is the same. */
.hm-strip{ display:grid; grid-template-columns:repeat(var(--n,5),minmax(0,1fr)); gap:var(--sv-gap); padding:0 var(--sv-gap); margin-bottom:var(--sv-gap); }
/* Two photos side by side (site.js keeps the strip to two): landscape, so
   the pair doesn't tower over the page on a wide screen. */
.hm-strip .sv-tile{ aspect-ratio:2/1; }
.hm-insta .sv-tile{ aspect-ratio:1/1; }
.hm-strip .sv-tile-name{ font-size:1.25rem; }

/* Instagram: the same deeper-rose band as New Arrivals, fading in and out. */
body.new-look .hm-band{ --sv-fade-top:7rem; --sv-fade-bottom:7rem; padding-top:2rem; padding-bottom:calc(var(--sv-fade-bottom) - 1rem); margin-top:2rem; background:var(--sv-band-flat); }
@supports (background:color-mix(in srgb, red 50%, blue)){
  body.new-look .hm-band{ background:var(--sv-band-bg); }
}

/* Visit: details beside a map, in one card */
.hm-visit .hm-card-copy{ gap:0; }
.hm-visit .visit-detail{ display:flex; gap:1rem; margin-bottom:1.1rem; }
.hm-visit .visit-detail .k{ font-weight:700; font-size:0.74rem; letter-spacing:0.08em; text-transform:uppercase; color:var(--sv-ink); min-width:5.25rem; padding-top:0.2rem; }
.hm-visit .visit-detail .v{ color:var(--sv-ink-soft); line-height:1.6; }
.hm-visit .sv-service-links{ margin-top:0.75rem; }
.hm-map{ position:relative; overflow:hidden; min-height:clamp(20rem,24vw,34rem); }
/* Google's free embed always draws its own address card in the top-left (no
   setting turns it off). The map is drawn 96px taller and shifted up by that
   much, so the card sits above the frame's edge; the pin and Google's credits
   along the foot stay in view. */
.hm-map iframe{ position:absolute; left:0; right:0; top:-96px; width:100%; height:calc(100% + 96px); border:0; display:block; filter:saturate(0.85) contrast(1.02); }
/* Until the visitor clicks "Show map" (site.js initMapGate): a quiet drawn
   street map -- linen, a few pale roads -- with a pin and the button. It sits
   in the open space left of the visit panel (centred on phones). */
.map-gate{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:0.875rem; padding:2rem 1.5rem; text-align:center;
  padding-right:calc(min(100%, 34rem) + 6vw + 1.5rem);
  background-color:#ece3d6;
  background-image:
    linear-gradient(112deg, transparent 46%, rgba(255,255,255,0.85) 46.4%, rgba(255,255,255,0.85) 48.6%, transparent 49%),
    linear-gradient(18deg, transparent 61%, rgba(255,255,255,0.7) 61.3%, rgba(255,255,255,0.7) 62.6%, transparent 62.9%),
    linear-gradient(160deg, transparent 27%, rgba(255,255,255,0.6) 27.3%, rgba(255,255,255,0.6) 28.2%, transparent 28.5%),
    repeating-linear-gradient(0deg, transparent 0 3.4rem, rgba(176,141,87,0.12) 3.4rem calc(3.4rem + 1px)),
    repeating-linear-gradient(90deg, transparent 0 3.4rem, rgba(176,141,87,0.12) 3.4rem calc(3.4rem + 1px)); }
.map-gate-pin{ width:2.75rem; height:2.75rem; fill:var(--blush-line); stroke:#fff; stroke-width:1.2; filter:drop-shadow(0 0.4rem 0.6rem rgba(42,36,32,0.3)); }
.map-gate-pin circle{ fill:#fff; stroke:none; }
.map-gate-note{ max-width:17rem; margin:0; font-size:0.78rem; line-height:1.5; color:var(--sv-ink-soft); }
.map-gate-note a{ color:inherit; text-decoration:underline; }
@media(max-width:860px){ .map-gate{ padding-right:1.5rem; } }

/* ---------- gallery page ----------
   A few good photos, each given room, rather than every piece at once.
   Hero: one full-width photo with the title set large and centred on it,
   under the see-through nav like the other pages (a light wash at the top
   keeps the nav readable, a soft shade behind the title keeps it readable).
   Then three sections, all filled by gallery-landing.js:
   Our Favourites  a justified wall: every photo whole, at its own shape,
                   side by side in rows that each fill the width exactly,
                   each numbered (No. 01) with its caption under it.
   Upholstery      on cream between gold hairlines (like the services page's
                   process band): the copy beside a loose stack of photo
                   prints, white-bordered, that you flip through.
   Painting        before / after sliders (.ba-slider, style.css), the first
                   one large.
   Favourites and Upholstery photos open in a lightbox (.gl-lightbox).
   Instagram sits at the foot on the same deeper-rose band as the home page. */
.gl-hero{ position:relative; display:flex; align-items:center; justify-content:center; min-height:max(30rem, 44vw); padding:max(7rem, 9vw) var(--sv-gap) max(3rem, 5vw); text-align:center; color:#fff; background:var(--iron); overflow:hidden; }
.gl-hero-photo{ position:absolute; inset:0; opacity:0; transition:opacity .6s ease; }
.gl-hero-photo.is-in{ opacity:1; }
/* Several hero photos glide past in a loop (gallery-landing.js): a row of
   full-size slides moved as one, with a copy of the first on the end so the
   loop never runs backwards. Dots under the title jump to a photo. */
.gl-hero-track{ position:absolute; inset:0; display:flex; transition:transform 1.4s cubic-bezier(.65,0,.35,1); }
.gl-hero-slide{ flex:0 0 100%; height:100%; }
.gl-hero-dots{ position:absolute; left:50%; bottom:1.5rem; transform:translateX(-50%); z-index:3; display:flex; gap:0.5rem; }
/* Shade only behind the centred title, fading to nothing well before the
   edges, so the header floats on the clean photo like the Upholstery page's
   (no pale wash or dark corners up where the nav sits). */
.gl-hero::before{ content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(ellipse 58% 48% at 50% 60%, rgba(42,36,32,0.52), rgba(42,36,32,0.22) 60%, rgba(42,36,32,0) 100%); }
.gl-hero-copy{ position:relative; z-index:2; display:flex; flex-direction:column; align-items:center; gap:1.25rem; max-width:48rem; }
.gl-hero .sv-badge{ color:#fff; border-color:rgba(255,255,255,0.85); }
.gl-hero h1{ font-style:italic; font-size:clamp(3.2rem,8vw,9rem); line-height:0.95; letter-spacing:-0.01em; text-shadow:0 0.25rem 2rem rgba(20,16,12,0.35); }
.gl-hero p{ font-size:1.1rem; line-height:1.65; color:rgba(255,255,255,0.92); max-width:34rem; margin:0; text-wrap:balance; text-shadow:0 1px 12px rgba(20,16,12,0.4); }

.gl-eyebrow{ display:block; text-align:center; font-size:0.72rem; font-weight:600; letter-spacing:0.22em; text-transform:uppercase; color:var(--gold); margin-bottom:0.875rem; }
.gl-sub{ text-align:center; font-family:var(--font-serif); font-style:italic; font-size:clamp(1rem,1.2vw,1.15rem); color:var(--sv-ink-soft); margin:0.5rem auto 0; padding:0 var(--sv-gap); }

/* Our Favourites: a justified wall (like a photo album's rows). Every
   piece hangs whole, at its own shape, in a thin gold frame on a blush mat;
   the photo is multiplied onto the mat, so a product shot's white
   background takes the mat's colour. Pieces sit side by side in rows, and
   each row grows until it fills the width exactly: a frame's grow and base
   width are its photo's shape (--ar, width / height, set by
   gallery-landing.js once the photo loads), so every frame in a row ends
   up the same height and none overlap. The last row keeps the target
   height (--gl-row) rather than stretching: the empty ::after takes its
   spare room. Sizes in vw, so the wall keeps its share of the screen at
   any zoom. Under each, its plate number and name. */
.gl-favs{ --gl-row:24vw; --gl-pad:clamp(0.5rem,1vw,1.25rem); --gl-mat:#fbf0ee; padding:clamp(4rem,7vw,8rem) 0 clamp(4.5rem,8vw,9rem); }
.gl-favs[hidden]{ display:none; }
.gl-spread{ display:flex; flex-wrap:wrap; align-items:flex-start; gap:max(2rem,3.5vw) max(1rem,2vw); margin:clamp(3rem,5vw,5rem) auto 0; padding:0 6vw; }
.gl-spread::after{ content:""; flex:10000 1 0; }
.gl-fav{ --ar:1; flex:var(--ar) 1 calc(var(--ar) * var(--gl-row) + 2 * var(--gl-pad)); min-width:0; margin:0; scroll-margin-top:8rem; }
.gl-fav > :is(a, button){ display:block; width:100%; padding:0; border:0; background:none; font:inherit; color:inherit; text-align:left; cursor:zoom-in; }
.gl-fav > a{ cursor:pointer; }
.gl-fav-photo{ display:block; padding:var(--gl-pad); background:var(--gl-mat); box-shadow:0 0 0 1px rgba(176,141,87,0.55), var(--sv-shadow-card); transition:transform .5s var(--ease-out), box-shadow .5s ease; }
.gl-fav-photo img{ display:block; width:100%; height:auto; aspect-ratio:var(--ar); object-fit:contain; mix-blend-mode:multiply; }
.gl-fav > :is(a, button):focus-visible .gl-fav-photo{ transform:translateY(-0.3rem); box-shadow:0 0 0 1px rgba(176,141,87,0.55), var(--sv-shadow-item-hover); }
@media (hover:hover){ .gl-fav > :is(a, button):hover .gl-fav-photo{ transform:translateY(-0.3rem); box-shadow:0 0 0 1px rgba(176,141,87,0.55), var(--sv-shadow-item-hover); } }
/* Museum-label style: plate number, then the name under it (one line each, so every frame in a row has the same label height). */
.gl-fav figcaption{ display:flex; flex-direction:column; align-items:flex-start; gap:0.3rem; min-width:0; margin-top:0.75rem; }
.gl-num{ flex-shrink:0; display:flex; align-items:center; gap:0.625rem; font-size:0.68rem; font-weight:600; letter-spacing:0.2em; text-transform:uppercase; color:var(--gold); }
.gl-num::before{ content:""; width:1.75rem; height:1px; background:var(--gold); }
.gl-fav-cap{ max-width:100%; font-family:var(--font-serif); font-style:italic; font-size:clamp(0.95rem,1.1vw,1.2rem); line-height:1.35; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.gl-fav.highlight .gl-fav-photo{ outline:0.25rem solid var(--blush-deep); outline-offset:0.375rem; }
.gl-spread .gallery-empty{ flex-basis:100%; }

/* Upholstery */
.gl-uph{ display:grid; grid-template-columns:minmax(0,0.85fr) minmax(0,1.15fr); align-items:center; gap:max(2.5rem, 6vw);
  padding:max(4.5rem, 8vw) max(1.5rem, 7vw); background:#fbf7f0; border-block:1px solid rgba(176,141,87,0.35); overflow:hidden; }
.gl-uph[hidden]{ display:none; }
.gl-uph-copy{ display:flex; flex-direction:column; align-items:flex-start; gap:1.25rem; }
.gl-uph-copy .gl-eyebrow{ text-align:left; margin:0; }
.gl-uph h2{ font-style:italic; font-size:clamp(2.8rem,5.5vw,5.5rem); line-height:0.95; }
.gl-uph-copy p{ font-family:var(--font-serif); font-size:clamp(1.05rem,1.3vw,1.3rem); line-height:1.6; color:var(--sv-ink-soft); max-width:26rem; margin:0; }
.gl-uph-nav{ display:flex; align-items:center; gap:1.25rem; margin:0.75rem 0 0.75rem; }
.gl-uph.single .gl-uph-nav{ display:none; }
.gl-arrow{ width:3rem; height:3rem; border-radius:50%; border:1px solid rgba(42,36,32,0.3); background:none; cursor:pointer; font-size:1.1rem; color:var(--sv-ink); transition:background-color .25s ease, color .25s ease, border-color .25s ease; }
.gl-arrow:focus-visible{ background:var(--sv-ink); color:#fff; border-color:var(--sv-ink); }
@media (hover:hover){ .gl-arrow:hover{ background:var(--sv-ink); color:#fff; border-color:var(--sv-ink); } }
.gl-uph-count{ min-width:4.5rem; text-align:center; font-family:var(--font-serif); font-style:italic; font-size:1.1rem; }
.gl-uph-stage{ display:flex; flex-direction:column; align-items:center; }
.gl-stack{ position:relative; width:min(100%, max(22rem, 37.8vw)); aspect-ratio:4/5; touch-action:pan-y; }
.gl-card{ position:absolute; inset:0; padding:clamp(0.6rem,1vw,0.9rem) clamp(0.6rem,1vw,0.9rem) clamp(2.4rem,3.6vw,3.4rem); background:#fff; border:0; cursor:pointer;
  box-shadow:0 1.5rem 3rem -1.5rem rgba(42,36,32,0.45), 0 0.25rem 0.75rem -0.25rem rgba(42,36,32,0.15);
  transition:transform .75s var(--ease-out), opacity .5s ease; }
.gl-card img{ display:block; width:100%; height:100%; object-fit:cover; background:var(--linen-deep); }
.gl-card[data-pos="0"]{ z-index:4; cursor:zoom-in; }
.gl-card[data-pos="0"]:focus-visible{ transform:translateY(-0.375rem); }
@media (hover:hover){ .gl-card[data-pos="0"]:hover{ transform:translateY(-0.375rem); } }
.gl-card[data-pos="1"]{ z-index:3; transform:translate(6%, 2%) rotate(4deg) scale(0.97); }
.gl-card[data-pos="2"]{ z-index:2; transform:translate(-6%, 3%) rotate(-5deg) scale(0.94); }
.gl-card:is([data-pos="3"], [data-pos="rest"]){ z-index:1; transform:translate(0, 4%) rotate(1deg) scale(0.9); opacity:0; pointer-events:none; }
.gl-card.gone{ z-index:5; transform:translate(-80%, -4%) rotate(-14deg); opacity:0; pointer-events:none; }
.gl-uph-cap{ min-height:1.4em; margin:clamp(2.5rem,4vw,3.5rem) 0 0; text-align:center; font-family:var(--font-serif); font-style:italic; font-size:clamp(1.05rem,1.3vw,1.25rem); color:var(--sv-ink); }

/* Painting */
.gl-paint{ padding:max(4.5rem, 8vw) max(1.25rem, 6vw) max(3.5rem, 6vw); }
.gl-paint[hidden]{ display:none; }
.gl-ba{ display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:max(2.5rem, 4vw) max(1.5rem, 3vw); max-width:93vw; margin:max(2.5rem, 4vw) auto 0; }
.gl-ba-item{ margin:0; }
/* The first pair large; a pair left on its own in the last row centred. */
.gl-ba-item:first-child{ grid-column:1 / -1; justify-self:center; width:min(100%, max(40rem, 71vw)); }
.gl-ba-item:first-child .ba-slider{ aspect-ratio:3/2; }
.gl-ba-item:not(:first-child):nth-child(even):last-child{ grid-column:1 / -1; justify-self:center; width:min(100%, max(26rem, 45.5vw)); }
.gl-ba .ba-caption{ text-align:center; }
.gl-ba .ba-slider .ba-handle-knob{ font-size:1rem; }

/* Lightbox (outside .lk, so plain values) */
html.gl-lb-open{ overflow:hidden; }
.gl-lightbox{ position:fixed; inset:0; z-index:200; touch-action:pan-y; display:flex; align-items:center; justify-content:center; gap:1.25rem; padding:4.5rem 1.25rem; background:rgba(30,24,20,0.93); }
.gl-lightbox[hidden]{ display:none; }
.gl-lightbox figure{ margin:0; min-width:0; display:flex; flex-direction:column; align-items:center; gap:1rem; }
.gl-lightbox img{ display:block; max-width:min(88vw, 80rem); max-height:calc(100vh - 11rem); max-height:calc(100dvh - 11rem); object-fit:contain; box-shadow:0 2rem 4rem -1rem rgba(0,0,0,0.6); }
.gl-lightbox figcaption{ color:rgba(255,255,255,0.92); font-family:var(--font-serif); font-style:italic; font-size:1.15rem; text-align:center; }
.gl-lightbox button{ flex-shrink:0; width:3rem; height:3rem; border-radius:50%; border:1px solid rgba(255,255,255,0.4); background:none; color:#fff; font-size:1.1rem; cursor:pointer; transition:background-color .2s ease; }
.gl-lightbox button:focus-visible{ background:rgba(255,255,255,0.14); }
@media (hover:hover){ .gl-lightbox button:hover{ background:rgba(255,255,255,0.14); } }
.gl-lb-close{ position:absolute; top:1.25rem; right:1.25rem; }
.gl-lightbox.single :is(.gl-lb-prev, .gl-lb-next){ visibility:hidden; }

@media(max-width:760px){
  .gl-favs{ --gl-row:34vw; --gl-pad:0.5rem; }
  .gl-spread{ gap:2rem 0.75rem; padding:0 1.25rem; }
  .gl-uph{ grid-template-columns:minmax(0,1fr); padding:4rem 1.5rem 4.5rem; gap:3rem; }
  .gl-stack{ width:min(78%, 22rem); }
  .gl-ba{ grid-template-columns:minmax(0,1fr); }
  .gl-ba-item:first-child .ba-slider{ aspect-ratio:4/3; }
  .gl-lightbox{ padding:4rem 0.75rem 5.5rem; }
  .gl-lightbox img{ max-width:100%; max-height:calc(100vh - 12rem); max-height:calc(100dvh - 12rem); }
  .gl-lb-prev, .gl-lb-next{ position:absolute; bottom:1.25rem; }
  .gl-lb-prev{ left:calc(50% - 3.75rem); }
  .gl-lb-next{ right:calc(50% - 3.75rem); }
}
@media(prefers-reduced-motion:reduce){
  .gl-card, .gl-fav-photo{ transition:none; }
}
/* Instagram tiles (site.js initInstagramGrid) flattened to the page's tiles */
.hm-insta .insta-tile, .hm-insta .insta-tile:nth-child(n){ transform:none; border-radius:0; aspect-ratio:1/1; box-shadow:var(--sv-shadow-item); }
@media (hover:hover){ .hm-insta .insta-tile:hover{ transform:none; box-shadow:var(--sv-shadow-item-hover); } }
.hm-insta .insta-bg{ transition:transform var(--hover-move); }
@media (hover:hover){ .hm-insta .insta-tile:hover .insta-bg{ transform:scale(1.05); } }
.gl-insta-cta{ text-align:center; padding:1rem var(--sv-gap) 0; }

/* ---------- About page ----------
   Its own look, shared with no other page: a storybook told through gilded
   oval frames, like antique oval mirrors and cameo portraits (no arches).
   .ab-frame is the frame: an oval photo ringed twice in gold (a 1px ring, a
   sliver of page pink, another ring), drawn with box-shadows so the rings
   follow the oval. Title beside one tall oval; the story as chapters
   on a gold timeline (roman-numeral medallions on the line, photo and copy
   swapping sides); the owner as a letter on cream paper with an oval
   portrait; the shop photos as three oval frames (the middle one taller
   when there are three); an address with a gold ornament to close. Sizes
   follow the window width so the photos keep their share at any zoom. */
.ab{ --ab-cream:#fbf7f0; --ab-ring:0 0 0 1px var(--gold), 0 0 0 0.5rem var(--blush), 0 0 0 calc(0.5rem + 1px) var(--gold); }
.ab-frame{ display:block; border-radius:50%; background-color:var(--linen-deep); background-size:cover; background-position:center; box-shadow:var(--ab-ring); }
.ab-eyebrow{ display:block; font-size:0.74rem; font-weight:600; letter-spacing:0.22em; text-transform:uppercase; color:var(--gold); }
.ab .sv-divider h2::before, .ab .sv-divider h2::after{ background:var(--gold); opacity:0.55; }

/* opening: title on the pink beside one tall oval */
.ab-hero{ display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,0.85fr); align-items:center; gap:6vw; padding:clamp(8.5rem,10vw,11rem) 7vw clamp(4rem,6vw,7rem); }
.ab-hero-copy{ display:flex; flex-direction:column; align-items:flex-start; gap:1.5rem; }
.ab-hero h1{ font-style:italic; font-size:clamp(3rem,6.4vw,7.5rem); line-height:0.98; text-wrap:balance; }
.ab-hero p{ font-family:var(--font-serif); font-size:clamp(1.15rem,1.5vw,1.5rem); line-height:1.55; color:#4a3a37; max-width:34rem; margin:0; }
.ab-hero-frame{ justify-self:center; width:min(100%, 30vw); aspect-ratio:3/4.2; }

/* the story: chapters on a gold timeline */
.ab-chapters{ padding:clamp(2rem,4vw,4rem) 7vw clamp(4rem,7vw,8rem); }
.ab-timeline{ position:relative; list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:clamp(4rem,7vw,8rem); }
.ab-timeline::before{ content:""; position:absolute; top:0; bottom:0; left:50%; width:1px; background:linear-gradient(transparent, var(--gold) 6%, var(--gold) 94%, transparent); }
.ab-chapter{ position:relative; display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr); align-items:center; gap:4vw; }
.ab-chapter-media{ display:flex; justify-content:flex-end; }
.ab-chapter-media .ab-frame{ width:min(100%, 24vw); aspect-ratio:3/4; }
.ab-node{ position:relative; z-index:1; display:flex; align-items:center; justify-content:center; width:3.5rem; height:3.5rem; border-radius:50%; background:var(--blush); border:1px solid var(--gold);
  box-shadow:0 0 0 0.3rem var(--blush), 0 0 0 calc(0.3rem + 1px) rgba(176,141,87,0.45);
  font-family:var(--font-serif); font-style:italic; font-weight:600; font-size:1.2rem; color:var(--gold); }
.ab-chapter-copy{ max-width:30rem; }
.ab-chapter-label{ display:block; font-family:var(--font-serif); font-style:italic; font-size:1.05rem; color:var(--gold); margin-bottom:0.75rem; }
.ab-chapter-copy h2{ font-size:clamp(1.9rem,3vw,3rem); line-height:1.05; margin-bottom:1.25rem; }
.ab-chapter-copy p{ font-size:1.06rem; line-height:1.8; color:var(--sv-ink-soft); margin:0 0 1.5rem; }
.ab-chapter-flip .ab-chapter-media{ order:3; justify-content:flex-start; }
.ab-chapter-flip .ab-chapter-copy{ order:1; justify-self:end; text-align:right; }
.ab-chapter-flip .ab-node{ order:2; }

/* the owner: a letter on cream paper */
.ab-letters{ display:grid; grid-template-columns:repeat(auto-fit, minmax(min(100%, 26rem), 1fr)); gap:4vw; padding:clamp(4rem,6vw,6rem) 7vw; max-width:72rem; margin:0 auto; }
.ab-letter{ position:relative; display:flex; flex-direction:column; align-items:center; text-align:center; margin-top:4.5rem; padding:7.5rem clamp(1.75rem,5vw,4.5rem) 3.5rem; background:var(--ab-cream);
  box-shadow:inset 0 0 0 1px var(--gold), inset 0 0 0 0.5rem var(--ab-cream), inset 0 0 0 calc(0.5rem + 1px) rgba(176,141,87,0.55), var(--sv-shadow-card); }
.ab-medallion{ position:absolute; top:-4.5rem; left:50%; width:9rem; height:11rem; margin-left:-4.5rem; border-radius:50%; background-color:var(--linen-deep); background-size:cover; background-position:center;
  box-shadow:0 0 0 1px var(--gold), 0 0 0 0.4rem var(--ab-cream), 0 0 0 calc(0.4rem + 1px) var(--gold); }
.ab-ornament-sm{ width:min(100%, 12rem); margin:0 0 0.5rem; }
.ab-letter blockquote{ font-family:var(--font-serif); font-style:italic; font-weight:500; font-size:clamp(1.4rem,2.2vw,2.1rem); line-height:1.4; color:var(--sv-ink); margin:1rem 0 2rem; text-wrap:balance; }
.ab-sign{ font-family:var(--font-serif); font-style:italic; font-weight:600; font-size:clamp(1.6rem,2.4vw,2.2rem); }
.ab-role{ margin-top:0.5rem; font-size:0.74rem; font-weight:600; letter-spacing:0.2em; text-transform:uppercase; color:var(--gold); }

/* inside the shop: three oval frames, the middle one taller */
.ab-triptych-wrap{ padding:clamp(2rem,4vw,4rem) 7vw clamp(3rem,5vw,6rem); }
.ab-triptych{ display:flex; justify-content:center; align-items:flex-end; gap:3.5vw; padding-top:1.5rem; }
.ab-triptych .ab-frame{ flex:1 1 0; max-width:24vw; aspect-ratio:3/4; transition:filter .6s ease; }
.ab-triptych.ab-odd .ab-frame:nth-child(2):nth-last-child(2){ aspect-ratio:3/4.7; }   /* three photos: the middle one taller */
@media (hover:hover){ .ab-triptych .ab-frame:hover{ filter:brightness(1.05) saturate(1.05); } }

/* close: an address under a gold ornament (two rules and a diamond) */
.ab-close{ display:flex; flex-direction:column; align-items:center; text-align:center; gap:1rem; padding:clamp(3rem,5vw,5rem) 7vw clamp(5rem,8vw,8rem); }
.ab-ornament{ position:relative; width:min(100%, 22rem); height:0.75rem; margin-bottom:0.75rem;
  background:linear-gradient(var(--gold),var(--gold)) 0 50% / calc(50% - 1.25rem) 1px no-repeat, linear-gradient(var(--gold),var(--gold)) 100% 50% / calc(50% - 1.25rem) 1px no-repeat; }
.ab-ornament::before{ content:""; position:absolute; left:50%; top:50%; width:0.55rem; height:0.55rem; background:var(--gold); transform:translate(-50%,-50%) rotate(45deg); }
.ab-close h2{ font-style:italic; font-size:clamp(2.2rem,4.2vw,4.2rem); line-height:1.05; }
.ab-close p{ font-size:1.06rem; line-height:1.75; color:var(--sv-ink-soft); max-width:32rem; margin:0 0 1rem; }
.ab-close-links{ display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:1rem 2rem; }

@media(max-width:860px){
  .ab-hero{ grid-template-columns:1fr; padding:7.5rem 1.5rem 3rem; gap:3rem; }
  .ab-hero-frame{ display:none; }   /* phones: straight from the title to the chapters */
  .ab-chapters{ padding:1.5rem 1.5rem 4rem; }
  .ab-timeline::before{ left:1.75rem; }
  .ab-chapter, .ab-chapter-flip{ grid-template-columns:3.5rem minmax(0,1fr); gap:1.5rem 1.25rem; align-items:start; }
  .ab-node, .ab-chapter-flip .ab-node{ order:0; grid-row:1 / span 2; }
  .ab-chapter-media, .ab-chapter-flip .ab-chapter-media{ order:1; justify-content:flex-start; }
  .ab-chapter-media .ab-frame{ width:min(100%, 18rem); }
  .ab-chapter-copy, .ab-chapter-flip .ab-chapter-copy{ order:2; grid-column:2; justify-self:start; text-align:left; }
  .ab-letters{ padding:4rem 1.5rem; }
  .ab-triptych-wrap{ padding:1.5rem 1rem 3rem; }
  .ab-triptych{ gap:1.5rem; }
  .ab-triptych .ab-frame{ max-width:none; }
  .ab-close{ padding:3rem 1.5rem 5rem; }
}

@media(max-width:860px){
  .hm-card{ grid-template-columns:1fr; }
  .hm-card-photo{ min-height:16rem; }
  .hm-card-copy{ padding:2rem 1.25rem; }
  body.new-look .hm-card, body.new-look :is(#founder, #visit) .hm-card{ align-items:flex-end; justify-content:center; min-height:max(34rem, 120vw); padding:1rem; }
  body.new-look .hm-card > .hm-card-copy{ width:100%; padding:1.75rem 1.5rem; }
  /* Intro: the storefront photo above, uncovered, the panel just below it. */
  body.new-look .hm-intro .hm-card{ flex-direction:column; align-items:stretch; min-height:0; padding:0 0 1rem; background:none; }
  body.new-look .hm-intro .hm-card > .hm-card-photo{ order:-1; position:relative; z-index:0; height:62vw; }
  body.new-look .hm-intro .hm-card > .hm-card-copy{ z-index:1; width:auto; margin:0 1rem; }
  /* Visit: the map above, uncovered (pin mid-map, Google's credits along its foot), the panel just below. */
  body.new-look .hm-visit .hm-card{ flex-direction:column; align-items:stretch; min-height:0; padding:0 0 1rem; background:none; }
  /* align-self: the #visit rule above aligns the card's children to the right
     (flex-end), which left the map 0px wide on phones. */
  body.new-look .hm-visit .hm-card > .hm-map{ order:-1; position:relative; z-index:0; height:22rem; align-self:stretch; }
  body.new-look .hm-visit .hm-card > .hm-card-copy{ z-index:1; width:auto; margin:0 1rem; }
  .hm-strip{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  /* The owner's quote: about half a screen, not a whole one, so the shop
     stays the page's focus. */
  body.new-look #founder .hm-card{ min-height:max(20rem, 66vw); }
  .hm-founder-copy blockquote{ font-size:1.3rem; margin-bottom:0.75rem; }
  /* Same for the services card; its two photos stand upright again. */
  body.new-look #craft .hm-card{ min-height:max(22rem, 72vw); }
  .hm-strip .sv-tile{ aspect-ratio:4/5; }
  /* The intro: tighter words under its photo, so the shop comes sooner. */
  body.new-look .hm-intro .hm-card > .hm-card-copy{ padding:1.25rem 1.25rem 1.5rem; }
  .hm-intro-heading{ font-size:1.6rem; margin-bottom:0.75rem; }
  .hm-intro-text{ font-size:0.95rem; line-height:1.55; margin-bottom:1rem; }
  /* Two columns: four Instagram photos fill two rows; a fifth sat alone. */
  .hm-insta > :nth-child(n+5){ display:none; }
  .hm-map{ min-height:18rem; }
  body.new-look .hm-head{ padding-top:2.5rem; }
  /* Phones: an even grid of two square photos, every category in view at
     once, name and count centred below. An odd last tile sits centred. */
  .sv-mosaic{ grid-template-columns:repeat(2, minmax(0,1fr)); grid-auto-rows:auto; gap:1rem 0.5rem; padding:0 0.75rem; }
  .sv-mosaic a:first-child{ grid-row:auto; grid-column:auto; }
  .sv-mosaic > .sv-tile:last-child:nth-child(odd){ grid-column:1 / -1; justify-self:center; width:calc((100% - 0.5rem) / 2); }
  .sv-mosaic .sv-tile-photo{ flex:none; aspect-ratio:1/1; border-radius:0.2rem; background:#fff; }
  .sv-mosaic .sv-tile-photo::after{ border-radius:inherit; }
  .sv-mosaic .sv-tile-cap{ align-items:center; text-align:center; padding:0.6rem 0 0; }
  .sv-mosaic .sv-tile-name::after{ -webkit-clip-path:inset(0 calc(50% - 0.75rem)); clip-path:inset(0 calc(50% - 0.75rem)); }
  .sv-mosaic > .sv-tile:first-child .sv-tile-name, .sv-mosaic .sv-tile-name{ font-size:1.12rem; padding-bottom:0.3rem; }
  .sv-mosaic .sv-tile-cap small{ font-size:0.7rem; }
  .sv-b2-grid{ grid-template-columns:1fr; height:auto; }
  .sv-b2-main{ min-height:26rem; }
  .sv-b2-side{ grid-template-rows:none; grid-template-columns:repeat(var(--n,2),1fr); height:13rem; }
  .sv-section{ padding:2.5rem 1rem; }
  .sv-service{ align-items:flex-end; }
  .sv-service{ justify-content:center; min-height:max(30rem, 110vw); padding:1rem; }
  .sv-service-copy{ width:100%; padding:1.75rem 1.5rem; }
  body.new-look :is(#shopLandingBottom, #shopFavourites) .h-scroll-track .gallery-card{ width:clamp(9rem,42vw,12rem); }
}
@media (prefers-reduced-motion: reduce){
  #svRoot *, #svRootBottom *, .lk *{ transition:none !important; }
}
