/* Self-hosted fonts — no external CDN. Files in theme/fonts/, copied to /assets/fonts/ at build. */
@font-face{font-family:'DM Serif Display';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/dm-serif-display-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'DM Serif Display';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/dm-serif-display-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/inter-400-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/inter-400-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/inter-500-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;src:url('/assets/fonts/inter-500-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/inter-600-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;src:url('/assets/fonts/inter-600-latin.woff2') format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
:root { --display: 'DM Serif Display', 'Bodoni Moda', serif; --ink: #F4F1EC; --bg: #0C0C0E; --panel: #141417; --line: rgba(244,241,236,0.08); --gold: #E3DCD1; }
html { scroll-behavior: smooth; }
body { margin: 0; background: #0C0C0E; color: #F4F1EC; font-family: Inter, sans-serif; -webkit-font-smoothing: antialiased; }
a { color: #F4F1EC; text-decoration: none; }
a:hover { color: var(--gold); }
img { display: block; }
#galerija-strip::-webkit-scrollbar { display: none; }
#galerija-strip img { pointer-events: none; }
@keyframes strip-marquee { from { transform: translateX(0); } to { transform: translateX(-33.3333%); } }
/* Same trick for the trust band: three copies in the track, slide one third. */
@keyframes trust-marquee { from { transform: translateX(0); } to { transform: translateX(-33.3333%); } }
/* The band runs edge to edge, so both ends fade into the panel instead of
   cutting a card in half against the viewport edge. */
#trust-strip { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
                       mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%); }
#trust-strip::-webkit-scrollbar { display: none; }
/* The bands swallow pointer events on their images so a drag across the strip is a
   drag and not a native image-drag. That also makes an image inside a band
   unclickable, which is correct for the logos and wrong for the award photograph -
   it is the one card meant to open full screen. Handing it its events back is safe
   because the two things pointer-events:none was doing for it are now done
   properly: draggable="false" on the tag plus a dragstart guard in marquee() stop
   the native drag, and marquee() swallows the click that ends a real drag. */
#trust-strip img { pointer-events: none; }
#trust-strip [data-lightbox] img { pointer-events: auto; }
@keyframes thumb-run { from { left: 0%; transform: translateX(0%); } to { left: 100%; transform: translateX(-100%); } }


/* ------------------------------------------------------------------
   Runtime shims added by the port (steps/tools/dc-to-php.py).
   display:contents keeps these wrappers out of the flex/grid layout.
   ------------------------------------------------------------------ */
.dc-desktop,.dc-mobile,.dc-when{display:contents}
@media (max-width:1023px){.dc-desktop{display:none}}
@media (min-width:1024px){.dc-mobile{display:none}}
.dc-when[data-when="menuOpen"]{display:none}
html.menu-open .dc-when[data-when="menuOpen"]{display:contents}
.dc-when[data-when="servicesMenuOpen"]{display:none}
.dc-hasmenu:hover .dc-when[data-when="servicesMenuOpen"],
.dc-hasmenu:focus-within .dc-when[data-when="servicesMenuOpen"]{display:contents}
.dc-when[data-when="f.open"]{display:none}
.is-open > .dc-when[data-when="f.open"]{display:contents}
/* Contact form. The state class sits on [data-contact], not on the form: the "sent"
   panel is a SIBLING of the form, so form.is-sent could never reach it. */
.dc-when[data-when="sent"]{display:none}
[data-contact].is-sent .dc-when[data-when="sent"]{display:contents}
[data-contact].is-sent .dc-when[data-when="notSent"]{display:none}
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;z-index:200;background:var(--panel);padding:10px 16px}

/* ------------------------------------------------------------------
   Hover states.

   These replace the design export's inline style-hover="" attributes.
   Only 10 distinct effects exist across the whole site, so they are a
   small shared set rather than one class per element.

   WHY !important IS REQUIRED HERE:
   the design export styles every element with an inline style="" attribute.
   An inline declaration beats any class selector, so without !important a
   hover rule that changes `color` or `background` is silently ignored on the
   26 of 30 elements that set those properties inline - which is what left
   PISITE and the CENIK button unreadable. The original design got away with
   it because its JS runtime mutated the inline style directly.

   RULE: any effect that changes `background` must also set `color`, or the
   global `a:hover { color: var(--gold) }` paints bone text on a bone fill.
   ------------------------------------------------------------------ */
.hv-gold:hover         { color: var(--gold) !important; }
.hv-invert:hover       { background: #F4F1EC !important; color: #0C0C0E !important; border-color: #F4F1EC !important; }
.hv-invert-plain:hover { background: #F4F1EC !important; color: #0C0C0E !important; }
.hv-gold-fill:hover    { background: var(--gold) !important; color: #0C0C0E !important; }
.hv-outline-gold:hover { border-color: var(--gold) !important; color: var(--gold) !important; }
.hv-tint:hover         { background: color-mix(in srgb, var(--gold) 10%, transparent) !important; color: #F4F1EC !important; }

/* on a <button>, so a:hover cannot reach it - matches the design */
.hv-gold-bg:hover      { background: var(--gold) !important; }

/* image effects; the elements carry their own transition inline */
.hv-zoom:hover         { transform: scale(1.04) !important; filter: brightness(1.06) !important; }
.hv-zoom-sm:hover      { transform: scale(1.035) !important; }
.hv-bright:hover       { filter: brightness(1.04) saturate(1.04) !important; }

/* ------------------------------------------------------------------
   "Kaj fotografiram" grid, client doc 11.1/11.2: a three-across row of verticals,
   then two-across rows of big horizontals. Column counts need a media query,
   which an inline style attribute cannot express.
   ------------------------------------------------------------------ */
.grid-top{grid-template-columns:1fr}
.grid-pairs{grid-template-columns:1fr}
@media (min-width:700px){
  .grid-top{grid-template-columns:repeat(3,1fr)}
  .grid-pairs{grid-template-columns:repeat(2,1fr)}
}

/* ------------------------------------------------------------------
   Hero grid.

   The left column now carries a headline plus two paragraphs, so it earns
   more width than the photo. The inline rule was auto-fit/1fr, which can
   only ever hand both columns the SAME width - and a media query cannot be
   written in a style attribute, which is why this single layout rule lives
   here rather than on the element like everything else in the design.
   ------------------------------------------------------------------ */
/* The hero pair. BOTH sides cap their own content - the text block at 820px, the photo
   frame at 86vh x its aspect ratio - while the grid keeps handing each column a share of
   whatever width the viewport has. Whatever neither side uses shows up as a gulf down the
   middle, and it grows as you zoom, because zooming shrinks the viewport height that the
   photo's cap is measured against. Hence: a tighter gap, and a column split that leans
   less far toward the text than 1.15/0.85 did, so the photo can take up more of what
   is there. */
.hero-grid{display:grid;align-items:center;gap:clamp(28px,3.2vw,56px);
    grid-template-columns:repeat(auto-fit,minmax(min(480px,100%),1fr))}
/* The photo column is sized by the PHOTO, not by a fraction of the page. A fractional
   track (it was 1.15fr) is always wider than a height-capped portrait, so the frame
   floated in it with slack down both sides while the heading stopped short on the other
   side of the gap - and the slack grew as you zoomed, because zooming shrinks the
   viewport height the frame is capped against. `auto` takes the slack out; the text
   column is 1fr and absorbs everything left over, so the only space between the two is
   the gap itself. The frame carries its own ceiling, so this track cannot run away. */
/* fit-content(46%) rather than plain auto: an auto track is sized from the image's
   INTRINSIC width (1707px on the homepage hero) before the frame's max-width clamps
   it, and a browser resolving those in the wrong order would hand the photo half the
   page. The 46% ceiling makes that impossible; below it the track still shrinks to
   whatever the frame actually is.

   0.85fr, NOT 1fr, on the text side. A single flexible track with a factor below 1
   takes only that share of the free space - the remaining 15% is left unallocated and
   settles at the END of the row, which pulls the photo in off the right margin rather
   than letting the text sprawl. Operator's call, and it is the reason the hero photo
   no longer lines up with the header's CTA on very wide screens. Raise it back to 1fr
   to restore that alignment.

   All three hero sections share this: home, service and location. The last two used to
   repeat the layout inline with slightly different numbers (460px, 74vh), which is how
   they drifted apart in the first place. */
@media (min-width:1100px){.hero-grid{grid-template-columns:minmax(0,0.85fr) fit-content(46%)}}

/* ------------------------------------------------------------------
   Lightbox. The frame reuses the homepage hero's treatment exactly:
   a 6px cream (--gold) border around the photo, nothing else.

   The operator asked for "a white frame like the one on the front page".
   Those are two different things - the front-page frame is this cream, not
   white - and matching the frame he pointed at wins over matching the word.

   Sized to fill the viewport: the masters are 1600px, so let the frame take
   the room rather than capping it at 1500. There is no caption strip any
   more, so the photo gets nearly the whole height back.
   ------------------------------------------------------------------ */
.lb{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
    gap:clamp(4px,1.5vw,18px);padding:clamp(10px,2vw,24px);
    background:rgba(8,8,10,.94);backdrop-filter:blur(6px)}
.lb[hidden]{display:none}
/* max-width is 100% of the FLEX CONTENT BOX, not 100vw - that already excludes
   .lb's padding. The two nav arrows are flex:0 0 auto beside it, so the frame is
   left to shrink (default flex-shrink, plus min-width:0) rather than being given
   a vw figure that would push them off the edge. */
/* The swipe track. Three slides - previous, current, next - laid side by side and
   parked on the middle one, so a drag reveals the neighbouring photograph instead of
   dragging one frame across empty space. .lb__view is the window; the track is 300%
   of it and one step is 33.3333% of the track. */
.lb__view{flex:1 1 auto;min-width:0;align-self:stretch;overflow:hidden;position:relative}
.lb__track{display:flex;width:300%;height:100%;transform:translateX(-33.3333%);
    will-change:transform}
.lb__slide{width:33.3333%;height:100%;display:flex;align-items:center;
    justify-content:center;box-sizing:border-box;padding:0 clamp(4px,1vw,14px)}
.lb__frame{margin:0;padding:6px;background:var(--gold);max-width:min(100%,1800px);
    min-width:0;display:flex;flex-direction:column;position:relative}
/* 72px = .lb's vertical padding at its 24px cap, plus the frame's own 12px, plus
   a little air. Without it a portrait photo runs off the bottom of the viewport. */
.lb__frame img{display:block;max-width:100%;max-height:calc(100vh - 72px);
    width:auto;height:auto;object-fit:contain}
.lb__x{position:absolute;z-index:2;top:clamp(10px,2vw,22px);right:clamp(10px,2vw,22px);
    background:none;border:0;color:var(--ink);font-size:34px;line-height:1;cursor:pointer;
    padding:6px 12px;opacity:.75;min-width:44px;min-height:44px;
    display:flex;align-items:center;justify-content:center}
.lb__x:hover{opacity:1;color:var(--gold)}
.lb__nav{background:none;border:0;color:var(--ink);font-size:44px;line-height:1;cursor:pointer;
    padding:10px 6px;opacity:.55;flex:0 0 auto;position:relative;z-index:2}
.lb__nav:hover{opacity:1;color:var(--gold)}
@media (max-width:700px){
  .lb__nav{position:absolute;bottom:14px;font-size:38px}
  .lb__prev{left:16px} .lb__next{right:16px}
  .lb__frame img{max-height:calc(100vh - 150px)}
}

/* ---------------------------------------------------------- live-offer dot
   Small red pulsing dot beside the −50 € discount markers. Purely decorative:
   the markup carries aria-hidden, so the offer still reads correctly without it.
   The dot itself is a fixed-size flex item and the expanding ring is an
   absolutely-positioned ::after, so nothing here can move the line box (CLS
   stays 0). Reduced-motion users get the dot without the pulse. */
.offer-dot {
  position: relative;
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #F2494E;
}
.offer-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: #F2494E;
  animation: offer-pulse 1.9s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
@keyframes offer-pulse {
  0%        { transform: scale(1);   opacity: 0.6; }
  70%, 100% { transform: scale(2.8); opacity: 0;   }
}
/* Header call button. Same red as the price dots (#F2494E), and it rings rather than
   pulses: a short decaying shake, then a long pause. The pause is the whole point - a
   handset that shook continuously would read as a broken animation, not as a phone. */
.call-icon {
  flex: none;
  display: block;
  color: #F2494E;
  transform-origin: 50% 60%;
  animation: call-ring 4.4s ease-in-out infinite;
}
/* The halo is the price dot's idiom applied to the handset: it radiates from the icon
   itself, contained, rather than washing the whole button. It runs on the ring's clock -
   same 4.4s cycle, blooming in the same keyframe window as the shake - and sits at
   z-index 0 under the handset's 1, so the red mark stays crisp on top of its own glow. */
.call-ico {
  position: relative;
  display: inline-flex;
  flex: none;
}
.call-ico::after {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: 0;
  border-radius: 50%;
  background: #F2494E;
  opacity: 0;
  animation: call-glow 4.4s ease-out infinite;
}
.call-icon { position: relative; z-index: 1; }
@keyframes call-glow {
  0%, 69%   { transform: scale(0.65); opacity: 0;    }
  72%       { transform: scale(0.65); opacity: 0.45; }
  88%, 100% { transform: scale(2.3);  opacity: 0;    }
}

@keyframes call-ring {
  0%, 70%   { transform: rotate(0deg);   }
  72%       { transform: rotate(-12deg); }
  74%       { transform: rotate(12deg);  }
  76%       { transform: rotate(-10deg); }
  78%       { transform: rotate(10deg);  }
  80%       { transform: rotate(-6deg);  }
  82%       { transform: rotate(6deg);   }
  84%, 100% { transform: rotate(0deg);   }
}

@media (prefers-reduced-motion: reduce) {
  .offer-dot::after { animation: none; }
  .call-icon { animation: none; }
  .call-ico::after { animation: none; opacity: 0; }
  /* The trust band still drags; it just stops drifting on its own. */
  #trust-track { animation: none; }
}

/* type="search" gets the browser its own clear button - WebKit paints one on hover,
   which sat beside ours and made two × in the same field. Ours stays: it is the one
   that is translated, keyboard-reachable and styled like the rest of the site. */
[data-price-search] input[type="search"]::-webkit-search-cancel-button,
[data-price-search] input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
          appearance: none;
}

/* The gallery wall. CSS columns rather than a grid: a grid row is as tall as its
   tallest cell, so a 2:3 portrait beside a 3:2 landscape either crops or leaves a hole.
   Columns let every photograph keep its own height and the wall closes up around them.

   The trade is reading order - columns fill top-to-bottom, so tile 2 is below tile 1,
   not beside it. For a photo wall nobody reads in sequence that is the right trade, and
   it is what every masonry gallery does.

   --gal-gap is set here and used by the inline margin on each figure, so the vertical
   gap between tiles and the horizontal gap between columns cannot drift apart. */
.gal-wall {
  --gal-gap: clamp(10px, 1.1vw, 16px);
  column-gap: var(--gal-gap);
  columns: 4;
}
@media (max-width: 1300px) { .gal-wall { columns: 3; } }
@media (max-width:  900px) { .gal-wall { columns: 2; } }
@media (max-width:  520px) { .gal-wall { columns: 1; } }

/* Visually hidden but read aloud. Used for the word behind the heart in the footer
   credit, so screen readers hear "made with love by TailoredFix" rather than skipping
   the emoji entirely. Not display:none - that would hide it from assistive tech too. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
         clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ------------------------------------------------------------------
   Contact form date picker.

   The only block in this file that styles a form control, because it is the
   only control the design did not ship - site.js builds the panel, so its
   markup cannot carry inline styles the way every hand-ported element does.

   Colours are the site's, one step lighter than the page so the panel reads as
   floating: #17171A on #0C0C0E. Day cells are 36px, comfortably past the 24px
   Lighthouse asks for on mobile, where target-size is audited.
   ------------------------------------------------------------------ */
.cal-field { position: relative; display: block; }
.cal-field > [data-cal-open] {
  position: absolute; right: 0; bottom: 6px; display: flex; align-items: center;
  justify-content: center; width: 28px; height: 28px; padding: 0; background: none;
  border: none; cursor: pointer; color: rgba(244,241,236,0.5);
  transition: color .18s ease;
}
.cal-field > [data-cal-open]:hover,
.cal-field > [data-cal-open][aria-expanded="true"] { color: var(--gold); }

.cal {
  position: absolute; z-index: 40; top: calc(100% + 10px); left: 0; width: 292px;
  max-width: calc(100vw - 40px); background: #17171A;
  border: 1px solid rgba(244,241,236,0.14); box-shadow: 0 22px 60px rgba(0,0,0,0.55);
  padding: 16px; font-family: Inter, sans-serif;
}
/* Flipped when the panel would otherwise run off the right edge of the viewport. */
.cal.cal--right { left: auto; right: 0; }

.cal__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cal__title {
  font-family: var(--display); font-size: 17px; letter-spacing: 0.02em;
  color: #F4F1EC; text-transform: capitalize;
}
.cal__nav {
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  background: none; border: 1px solid rgba(244,241,236,0.14); color: #F4F1EC;
  cursor: pointer; font-size: 13px; line-height: 1; transition: border-color .18s ease, color .18s ease;
}
.cal__nav:hover:not(:disabled) { border-color: var(--gold); color: var(--gold); }
.cal__nav:disabled { opacity: 0.28; cursor: default; }

.cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-top: 14px; }
.cal__dow {
  height: 26px; display: flex; align-items: center; justify-content: center;
  font-size: 9px; letter-spacing: 0.1em; font-weight: 600; color: rgba(244,241,236,0.42);
}
.cal__day {
  height: 36px; display: flex; align-items: center; justify-content: center;
  background: none; border: 1px solid transparent; color: #F4F1EC; font-family: inherit;
  font-size: 13.5px; cursor: pointer; transition: background-color .16s ease, color .16s ease, border-color .16s ease;
}
.cal__day:hover:not(:disabled) { background: rgba(244,241,236,0.09); }
.cal__day:disabled { color: rgba(244,241,236,0.2); cursor: default; }
.cal__day--pad { visibility: hidden; }
/* Today is outlined; the chosen day is filled. Both can be the same cell. */
.cal__day--today { border-color: rgba(227,220,209,0.55); }
.cal__day--on, .cal__day--on:hover { background: var(--gold); color: #0C0C0E; font-weight: 600; }
.cal__day:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

.cal__foot { margin-top: 12px; padding-top: 12px; border-top: 1px solid rgba(244,241,236,0.1); text-align: right; }
.cal__clear {
  background: none; border: none; cursor: pointer; padding: 6px 2px;
  font-family: inherit; font-size: 9.5px; letter-spacing: 0.18em; font-weight: 600;
  color: rgba(244,241,236,0.5); transition: color .18s ease;
}
.cal__clear:hover { color: var(--gold); }

/* ------------------------------------------------------------------
   Trust band: the Instagram mark on a linked credit.

   Absolute, so it costs the card no layout - the cards are a flex row whose
   height is set by the tallest one, and an inline mark would have widened the
   text column of every card to make room. Dim at rest, gold when the card is
   hovered: it is a hint that the card goes somewhere, not a second control.
   ------------------------------------------------------------------ */
.trust-ig {
  position: absolute; top: 2px; display: flex; line-height: 0;
  color: rgba(244,241,236,0.32); transition: color .18s ease; pointer-events: none;
}
a:hover > .trust-ig,
a:focus-visible > .trust-ig { color: var(--gold); }

/* ------------------------------------------------------------------
   Mobile menu disclosure groups (STORITVE, LOKACIJE).

   <details> gives the behaviour and the accessibility for free; all this does
   is take away the browser's default triangle - which cannot be styled and sits
   on the wrong side - and turn the design's own caret over when the group opens.
   ------------------------------------------------------------------ */
.mnav > summary { list-style: none; cursor: pointer; }
.mnav > summary::-webkit-details-marker { display: none; }
.mnav > summary::marker { content: ""; }
.mnav-caret { transition: transform .2s ease; }
.mnav[open] > summary .mnav-caret { transform: rotate(180deg); }

/* ------------------------------------------------------------------
   THE KIT — homepage equipment band.

   The products are near-black objects on a near-black page, so at rest each
   one sits on a soft radial wash that lifts it off the background. Without it
   a lens barrel simply disappears; with it the shape reads even before the
   photograph resolves.

   Each group is a flex block only as wide as its own cards, so the row packs
   itself: at 1100px the 2 cameras and 4 lenses fill line one and the four
   single-item groups fill line two, with no media query deciding it. Cards are
   a fixed 160px so a group of four and a group of one line up on the same grid.
   ------------------------------------------------------------------ */
.kit        { display: flex; flex-wrap: wrap; gap: clamp(26px, 3.4vw, 44px) clamp(28px, 3.6vw, 52px); }
.kit-group  { display: flex; flex-direction: column; gap: 14px; flex: 0 1 auto; }
.kit-group__label {
  font-size: 10.5px; letter-spacing: 0.16em; font-weight: 500;
  text-transform: uppercase; color: rgba(244,241,236,0.55);
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.kit-row    { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: clamp(14px, 1.8vw, 26px); }
.kit-card   { width: 160px; display: flex; flex-direction: column; align-items: center; gap: 12px; }

/* The wash. A pseudo-element rather than a background on the tile itself, so it
   can brighten on hover without the artwork inheriting the transition.

   It is BLURRED as well as faint. A radial-gradient alone still resolves to a
   visible disc - the eye finds the radius where the last stop lands, however low
   the alpha - and ten discs read as ten plates behind the products. A real
   filter: blur() destroys that edge, so what is left is a suggestion of light
   rather than a shape. The element is inset NEGATIVE so the blur has room to
   fall off outside the tile instead of being cut square at its bounds. */
.kit-card__art { position: relative; display: block; width: 100%; line-height: 0; }
.kit-card__art::before {
  content: ""; position: absolute; inset: -22%;
  background: radial-gradient(circle at 50% 50%,
              rgba(244,241,236,0.115) 0%, rgba(244,241,236,0.072) 26%,
              rgba(244,241,236,0.034) 48%, rgba(244,241,236,0.01) 68%, transparent 84%);
  filter: blur(22px);
  /* The gradient is authored at FULL strength and held at half opacity at rest, so
     hover has somewhere to go: opacity cannot exceed 1, so a wash already at 1 has
     no headroom and the hover state would silently do nothing. */
  opacity: .5;
  transition: opacity .45s ease, transform .45s cubic-bezier(.22,.61,.36,1);
}
.kit-card img {
  position: relative; width: 100%; height: auto; aspect-ratio: 1 / 1;
  object-fit: contain;
  transition: transform .45s cubic-bezier(.22,.61,.36,1), filter .45s ease;
}
.kit-card__name {
  font-size: 13.5px; line-height: 1.45; text-align: center;
  color: rgba(244,241,236,0.7); transition: color .3s ease;
}

/* Hover lifts the product a little and brings the wash up to full. Scoped to
   devices that actually hover: on a touch screen :hover sticks after a tap and
   one card would stay lit for the rest of the visit. */
@media (hover: hover) {
  /* Hover raises the same wash rather than swapping the gradient: animating opacity
     is one composited property, where animating background repaints every frame. */
  .kit-card:hover .kit-card__art::before { opacity: 1; transform: scale(1.08); }
  .kit-card:hover img       { transform: translateY(-5px) scale(1.06); filter: brightness(1.1); }
  .kit-card:hover .kit-card__name { color: var(--gold); }
}

@media (max-width: 560px) {
  /* Two per row on a phone rather than one 160px card marooned in a wide column. */
  .kit-card { width: calc(50% - clamp(7px, 0.9vw, 13px)); }
  .kit-group, .kit-row { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .kit-card img, .kit-card__art::before { transition: none; }
  .kit-card:hover img { transform: none; }
  .kit-card:hover .kit-card__art::before { transform: none; }
}
