/*
Theme Name: Sokolowski Minerals
Theme URI: https://sokolowskiminerals.com.pl
Author: Ola Hola
Description: Custom theme for the Museum of Minerals and Precious Stones in Kudowa-Zdroj. Ported from the approved v5 prototype. No page builder, no framework, one stylesheet, ~60 lines of vanilla JS.
Version: 1.0.0
Requires at least: 6.5
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sokolowski
Tags: custom-menu, translation-ready, accessibility-ready
*/

/* =========================================================================
   0. Naming conventions used throughout this file.

   Class names describe what a thing IS, not what it looks like, and are
   prefixed with the section they belong to so a selector can be traced back to
   one template part:

     .hero-*          hero panel and facts line   template-parts/hero.php
     .case-rail*      display-case photographs    template-parts/museum.php
     .uv-lamp*        fluorescent minerals        template-parts/uv.php
     .feature-row*    shop and grown minerals     template-parts/shop.php
     .post-*          article cards               template-parts/post-card.php
     .visit-*         hours, tickets, contact     template-parts/visit.php
     .rail-*          arrows and dots shared by both horizontal rails
     .article-*       single article and page templates

   Anything beginning .is- is a STATE toggled by assets/js/site.js rather than
   a style applied by the markup: .is-visible, .is-stuck, .is-lit, .is-touched,
   .is-current-section. Do not set these in PHP.

   Element ids are reserved for the handful of elements JavaScript addresses
   directly (#site-header, #hero-title, #hero-specimen, #primary-nav,
   #menu-toggle, #menu-scrim, #uv-lamp, #uv-toggle) and for the in-page section
   anchors the navigation links to (#muzeum, #sklep, #ciekawostki, #kontakt,
   #sala-uv). Those anchor ids are public URLs and must not be renamed.

   Custom properties set from the markup or from JavaScript:
     --reveal-index   position in a stagger, on any .reveal element
     --word-index     position of a word in the headline reveal
     --lamp-x/-y      pointer position inside the UV lamp
   Everything else beginning -- is a design token defined in :root below.
   ========================================================================= */

/* =========================================================================
   1. Self-hosted Figtree, OFL, served from the theme.

   Two faces because Google splits the family: the Polish diacritics
   (ł ą ę ó ś ż ź ć ń) live in latin-ext, not latin. Shipping only the latin
   file drops every accented character in the copy.

   The unicode-ranges are Google's own, unchanged. Note that neither subset
   contains U+2192, so the design's arrow is drawn as inline SVG instead of
   a text glyph.
   ========================================================================= */
@font-face{
  font-family:"Figtree";
  src:url("assets/fonts/figtree-latin.woff2") format("woff2");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
  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:"Figtree";
  src:url("assets/fonts/figtree-latin-ext.woff2") format("woff2");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
  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;
}

/* =========================================================================
   2. Prototype stylesheet, ported verbatim.
   Do not restyle. Colours, type scale, spacing and motion are approved.
   ========================================================================= */
:root{
  --white:#FFFFFF; --cream:#F0E4D6; --cream-2:#F8F1E9;
  --taupe:#83716F; --btn:#766363; --navy:#0F1729; --accent:#D89870; --rose:#C0A8A8;
  --ink:#0F1729; --ink-2:#5A5F6B; --ink-3:#8D919B;
  --line:rgba(15,23,41,.10); --line-2:rgba(15,23,41,.20);
  --s2:16px; --s3:24px; --s4:40px; --s5:64px; --s6:96px; --s7:144px; --r:20px;
  /* One width for the header, every section and the footer, so their edges line up. */
  --page-width:1300px;
  /* Height of the fixed #site-header: 20px padding above and below a 32px brand.
     The hero reserves this much at the top so it is never tucked under the header. */
  --header-height:72px;
  /* The same header once the page has scrolled and it tightens to 12px padding.
     Sections reached from the menu stop this far down, so the header never
     covers their first line. 68px on narrow screens, where the menu button is
     taller than the brand; see just below. */
  --header-stuck-height:56px;
  /* The one gap between neighbouring homepage sections, 64px on phones rising
     to 96px on desktop. Each section carries half of it above and half below,
     so any two sections, in any order the owners put them, sit exactly this
     far apart. */
  --section-space:clamp(4rem,2.5rem + 4.5vw,6rem);
  --d1:clamp(2.4rem,5.4vw,4.6rem); --d2:clamp(1.6rem,2.9vw,2.4rem);
  --body:clamp(1rem,1.02vw,1.0625rem); --micro:.75rem;
  --font:"Figtree",system-ui,-apple-system,sans-serif;
  --ease:cubic-bezier(.22,.61,.28,1);
}
@media (max-width:900px){:root{--header-stuck-height:68px}}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased}
body{background:var(--white);color:var(--ink);font-family:var(--font);
  font-size:var(--body);line-height:1.7;overflow-x:hidden}
img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
.container{width:min(100% - 2.5rem,var(--page-width));margin-inline:auto}
.section-label{font-size:var(--micro);font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);display:block}
h1,h2,h3{font-weight:800;letter-spacing:-.02em;text-transform:uppercase;line-height:1.06}
h1{font-size:var(--d1)}
h2{font-size:var(--d2);max-width:22ch;text-wrap:balance}
h3{font-size:1.0625rem;letter-spacing:.01em;line-height:1.3}
p+p{margin-top:1.1em}

#site-header{position:fixed;inset:0 0 auto;z-index:800;padding:20px 0;
  transition:padding .45s var(--ease),background .45s var(--ease),box-shadow .45s var(--ease)}
#site-header.is-stuck{padding:12px 0;background:rgba(255,255,255,.9);
  backdrop-filter:blur(16px);box-shadow:0 1px 0 var(--line)}
#site-header .container{display:flex;align-items:center;justify-content:space-between;gap:var(--s4)}
.site-brand{font-weight:800;font-size:1.2rem;line-height:1;display:grid;gap:3px}
.site-brand small{font-weight:600;font-size:.6rem;letter-spacing:.42em;color:var(--ink-3)}
nav ul{display:flex;gap:var(--s4);list-style:none}
nav a{font-size:.875rem;font-weight:500;color:var(--ink-2);position:relative;padding-bottom:3px}
nav a::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:1.5px;
  background:var(--accent);transform:scaleX(0);transform-origin:right;
  transition:transform .45s var(--ease)}
nav a:hover{color:var(--ink)}nav a:hover::after{transform:scaleX(1);transform-origin:left}
.locale{display:flex;gap:12px;font-size:var(--micro);font-weight:600;color:var(--ink-3)}
.locale b{color:var(--ink)}

.button{display:inline-flex;align-items:center;gap:10px;padding:15px 30px;border-radius:999px;
  background:var(--btn);color:#fff;font-weight:600;font-size:.9375rem;
  position:relative;overflow:hidden;isolation:isolate;transition:transform .45s var(--ease)}
.button::before{content:"";position:absolute;inset:0;background:var(--navy);z-index:-1;
  transform:translateY(101%);transition:transform .5s var(--ease)}
.button:hover{transform:translateY(-2px)}.button:hover::before{transform:translateY(0)}
.button svg{width:16px;height:16px;transition:transform .45s var(--ease)}
.button:hover svg{transform:translateX(4px)}
.button.button-outline{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--line-2)}
.button.button-outline:hover{color:#fff}

/* hero */
.hero{padding:calc(var(--s5) + 20px) 0 calc(var(--section-space) / 2)}
.reveal-word{display:inline-block;overflow:hidden;vertical-align:bottom}
.reveal-word>span{display:inline-block;transform:translateY(110%);
  transition:transform .85s var(--ease);transition-delay:calc(var(--word-index) * 55ms)}
.is-loaded .reveal-word>span{transform:translateY(0)}
html:not(.js-enabled) .reveal-word>span{transform:none}
.meta{display:flex;flex-wrap:wrap;gap:var(--s4);margin-top:var(--s4);
  padding-top:var(--s3);border-top:1px solid rgba(15,23,41,.14)}
.meta small{font-size:var(--micro);font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:#6E6A6A;display:block}
.meta b{font-size:.9375rem;font-weight:600;font-variant-numeric:tabular-nums}

.specimen-ticker{overflow:hidden;border-bottom:1px solid var(--line);padding:16px 0;margin-top:var(--s2);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.specimen-ticker-track{display:flex;gap:2rem;width:max-content;
  animation:roll 52s linear infinite}
.specimen-ticker:hover .specimen-ticker-track{animation-play-state:paused}
@keyframes roll{to{transform:translateX(-50%)}}
.specimen-ticker li{list-style:none;font-size:.9375rem;font-weight:500;color:var(--ink-2);
  white-space:nowrap;display:flex;align-items:center;gap:2rem}
.specimen-ticker li::after{content:"";width:5px;height:5px;border-radius:50%;
  background:var(--accent);flex:0 0 auto}


/* Homepage sections. The gap is padding, not margin, so it belongs to the
   section itself: a link to #kontakt or #sklep always lands the same way, with
   the tightened header, then half a section gap, then the section's first line. */
.page-section{padding-block:calc(var(--section-space) / 2);scroll-margin-top:var(--header-stuck-height)}
.admin-bar .page-section{scroll-margin-top:calc(var(--header-stuck-height) + 32px)}
@media screen and (max-width:782px){.admin-bar .page-section{scroll-margin-top:calc(var(--header-stuck-height) + 46px)}}
.section-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr);
  gap:var(--s5);align-items:start;margin-bottom:var(--s5)}
.section-head p{color:var(--ink-2);max-width:58ch}
.section-head h2{margin-top:14px}

/* display-case rail (.case-rail) */
.case-rail{overflow-x:auto;
  scrollbar-width:none;-ms-overflow-style:none}
.case-rail::-webkit-scrollbar{display:none}
.case-rail figure{flex:0 0 clamp(300px,30vw,430px)}
.case-rail figure img{border-radius:14px;aspect-ratio:3/4;object-fit:cover;width:100%}
/* The strip of photographs inside the rail. On phones the rail scrolls it
   natively; on desktop, while drifting, site.js moves the strip itself with a
   transform and the rail stops scrolling. A transform can move by fractions of
   a pixel, so the slow drift glides instead of stepping a pixel at a time. */
.case-rail-track{display:flex;gap:var(--s2)}
.case-rail.is-drifting{overflow:hidden}
.case-rail.is-drifting .case-rail-track{will-change:transform}
/* The arrows sit right under the photographs rather than a full step below. */
.case-rail-wrap .rail-controls{margin-top:12px}

.prose-columns{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s4);
  margin-top:var(--s5);color:var(--ink-2);align-items:start}
.section-intro{font-size:1.125rem;color:var(--ink);max-width:60ch}

/* UV lamp */
.uv-lamp-card{border-radius:var(--r);background:#14110F;color:#F2ECE4;
  padding:clamp(2rem,4vw,3.5rem)}
.uv-lamp-card h2{color:#fff}
.uv-lamp-card > p{color:#B4ABA1;max-width:54ch;margin:12px 0 var(--s4)}
.uv-lamp{position:relative;border-radius:14px;overflow:hidden;aspect-ratio:4/5;
  background:#000;--lamp-x:50%;--lamp-y:50%;--lamp-radius:clamp(80px,30vw,170px)}
@media (min-width:700px){.uv-lamp{aspect-ratio:16/10}}
.uv-lamp img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.uv-lamp .daylight-layer{z-index:2;transition:opacity .7s var(--ease);
  filter:saturate(.28) brightness(1.75) contrast(.88)}
.uv-lamp.is-lit .daylight-layer{opacity:0}
.uv-lamp .lamp-ring,.uv-lamp .lamp-hint{display:none}
@media (pointer:fine){
  .uv-lamp{cursor:none}
  .uv-lamp .daylight-layer{
    -webkit-mask-image:radial-gradient(circle var(--lamp-radius) at var(--lamp-x) var(--lamp-y),transparent 0%,#000 78%);
            mask-image:radial-gradient(circle var(--lamp-radius) at var(--lamp-x) var(--lamp-y),transparent 0%,#000 78%)}
  .uv-lamp .lamp-ring{display:block;position:absolute;z-index:3;left:var(--lamp-x);top:var(--lamp-y);
    width:calc(var(--lamp-radius) * 2);height:calc(var(--lamp-radius) * 2);
    margin:calc(var(--lamp-radius) * -1) 0 0 calc(var(--lamp-radius) * -1);
    border-radius:50%;pointer-events:none;
    box-shadow:inset 0 0 60px rgba(124,232,180,.22);border:1px solid rgba(124,232,180,.35)}
  .uv-lamp .lamp-hint{display:block;position:absolute;left:50%;bottom:18px;transform:translateX(-50%);
    z-index:5;font-size:var(--micro);font-weight:600;letter-spacing:.1em;text-transform:uppercase;
    color:#7CE8B4;background:rgba(0,0,0,.55);padding:7px 14px;border-radius:999px;
    transition:opacity .4s var(--ease)}
  .uv-lamp.is-touched .lamp-hint{opacity:0}
  .uv-toggle-button{display:none}
}
.uv-toggle-button{margin-top:var(--s3);background:transparent;color:#F2ECE4;font-family:inherit;
  cursor:pointer;box-shadow:inset 0 0 0 1.5px rgba(124,232,180,.45)}
.uv-toggle-button::before{background:#7CE8B4}
.uv-toggle-button[aria-pressed="true"]{color:#14110F;background:#7CE8B4;
  box-shadow:inset 0 0 0 1.5px #7CE8B4}
.uv-lamp .lamp-hint{position:absolute;left:50%;bottom:18px;transform:translateX(-50%);z-index:5;
  font-size:var(--micro);font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:#7CE8B4;background:rgba(0,0,0,.55);padding:7px 14px;border-radius:999px;
  transition:opacity .4s var(--ease)}
.uv-lamp.is-touched .lamp-hint{opacity:0}

.feature-row{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s5);align-items:center}
.feature-row img{border-radius:14px;width:100%;object-fit:cover;aspect-ratio:4/3}
.feature-row p{color:var(--ink-2);margin-top:14px;max-width:46ch}
.feature-row-tinted{background:var(--cream-2);border-radius:var(--r);padding:clamp(2rem,4vw,3.5rem)}

.post-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:var(--s3)}
.post-card{border-radius:14px;padding:var(--s3);box-shadow:inset 0 0 0 1px var(--line);
  display:grid;align-content:start;gap:12px;
  transition:transform .5s var(--ease),box-shadow .5s var(--ease)}
.post-card:hover{transform:translateY(-6px);box-shadow:inset 0 0 0 1px transparent,0 18px 36px rgba(15,23,41,.09)}
.post-card time{font-size:var(--micro);font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.post-card p{font-size:.9375rem;color:var(--ink-2);line-height:1.6}
.post-card .post-card-more{font-size:.875rem;font-weight:600;color:var(--accent)}

.owners-quote{border-radius:var(--r);background:var(--cream);text-align:center;
  padding:clamp(3rem,7vw,6rem) var(--s4)}
.owners-quote blockquote{font-size:clamp(1.35rem,2.7vw,2.05rem);font-weight:500;line-height:1.35;
  letter-spacing:-.015em;max-width:26ch;margin-inline:auto;text-wrap:balance}
.owners-quote figcaption{margin-top:var(--s3);font-size:.9375rem;color:#6E6A6A;font-weight:500}

.visit-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--s3)}
.visit-card{background:var(--cream-2);border-radius:14px;padding:var(--s4) var(--s3)}
.visit-card h3{margin-bottom:var(--s3)}
.detail-row{display:flex;justify-content:space-between;gap:var(--s2);padding:11px 0;
  border-bottom:1px solid rgba(15,23,41,.09);font-size:.9375rem;font-variant-numeric:tabular-nums}
.detail-row span:first-child{color:var(--ink-2)}.detail-row span:last-child{font-weight:600}
.season-label{font-size:var(--micro);font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent);margin:var(--s3) 0 6px}
.season-label:first-of-type{margin-top:0}
.card-note{font-size:.875rem;color:var(--ink-2);margin-top:var(--s3)}
.visit-card .button{margin-top:var(--s3)}
footer{border-top:1px solid var(--line);font-size:.875rem;color:var(--ink-3)}

.js-enabled .reveal{opacity:0;transform:translateY(24px);
  transition:opacity .95s var(--ease),transform .95s var(--ease);
  transition-delay:calc(var(--reveal-index,0) * 80ms)}
.js-enabled .reveal.is-visible{opacity:1;transform:none}

@media (max-width:900px){
  .section-head,.feature-row,.prose-columns{grid-template-columns:1fr}
  .case-rail{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
  .js-enabled .reveal,.reveal-word>span{opacity:1;transform:none}
  .specimen-ticker{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
  .specimen-ticker-track{animation:none}
  .uv-lamp .daylight-layer{opacity:0}
  .uv-lamp .lamp-hint{display:none}
  html{scroll-behavior:auto}
}

/* =========================================================================
   3. WordPress additions.
   Everything below is new: it exists because the prototype was a single
   static file and a theme has to handle admin bar, skip links, editor
   output and an article template the prototype never had.
   ========================================================================= */

.screen-reader-text{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.screen-reader-text:focus{
  position:fixed!important;top:12px;left:12px;z-index:2000;width:auto;height:auto;
  clip:auto;clip-path:none;padding:12px 20px;border-radius:999px;
  background:var(--navy);color:#fff;font-weight:600;font-size:.875rem}

.admin-bar #site-header{top:32px}
@media screen and (max-width:782px){.admin-bar #site-header{top:46px}}

/* Post archive cards need a real heading colour, the prototype used <h3>. */
.post-card h3{color:var(--ink)}

/* -------- article pages (single.php and page.php) --------
   Built from the front page's own parts so an article belongs to the same site:
   the hero's gradient panel as its header, the section label, the article
   cards. Two widths are shared by the header and the body, so their edges line
   up down the whole page:

     --article-wide   the header panel, and the photographs in the article
     --article-text   the title, the date and every paragraph

   The body is a three-column grid. Everything the owners write lands in the
   middle column; photographs step out across all three. */
.article-page{--article-wide:60rem;--article-text:46rem;
  padding-top:calc(var(--header-height) + var(--s4))}

.article-header{position:relative;isolation:isolate;overflow:hidden;
  width:min(100% - 2.5rem,var(--article-wide));margin-inline:auto;border-radius:var(--r);
  padding:clamp(2.5rem,6vw,4.5rem) var(--s3);
  /* How strongly the hero's gradient shows through. The front page uses it at
     full strength; an article only nods to it so the reading page stays light.
     0 is plain white, 1 matches the hero. */
  --article-header-tint:.35;
  background:var(--white)}
/* The gradient sits on its own layer so its strength can be dialled down
   without touching the title or the date above it. */
.article-header::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  opacity:var(--article-header-tint);
  background:
    radial-gradient(60% 90% at 85% 20%,rgba(253,242,216,.9),transparent 70%),
    linear-gradient(108deg,var(--cream) 0%,var(--cream) 40%,var(--rose) 78%,var(--taupe) 100%)}
/* Lighter grain to match the lighter panel. */
.article-header::after{opacity:.025}
.article-header-inner{max-width:var(--article-text);margin-inline:auto}
.article-header h1{margin-top:14px;max-width:none;font-size:clamp(2rem,3.6vw,3rem);line-height:1.05;text-wrap:balance}
.article-meta{margin:var(--s3) 0 0;font-size:.9375rem;color:#5A5F6B;font-variant-numeric:tabular-nums}

/* The section label doubles as the way back to the front-page section. */
.article-back-link{display:inline-flex;align-items:center;gap:8px;transition:color .35s var(--ease)}
.article-back-link svg{width:14px;height:14px;transition:transform .45s var(--ease)}
.article-back-link:hover{color:var(--ink)}
.article-back-link:hover svg{transform:translateX(-3px)}

.article-body{width:min(100% - 2.5rem,var(--article-wide));margin-inline:auto;
  display:grid;
  grid-template-columns:[wide-start] minmax(0,1fr) [text-start] minmax(0,var(--article-text)) [text-end] minmax(0,1fr) [wide-end];
  padding:var(--s5) 0 calc(var(--section-space) / 2);
  font-size:1.125rem;line-height:1.8;color:#3E4149}
.article-body > *{grid-column:text;margin:0}
.article-body > * + *{margin-top:1.25em}
/* Nothing adds space above the first block; the body's own top padding does that.
   Matters on pages that open with a heading, such as the privacy policy. */
.article-body > :first-child{margin-top:0}

/* The opening paragraph is set larger, like the section introductions on the front page. */
.article-body > p:first-child,
.article-body > .article-lead-image + p{font-size:1.25rem;line-height:1.7;color:var(--ink)}

/* Photographs step out to the wide width, so their edges meet the header's.
   The block editor writes a fixed pixel width and its own corner radius onto
   each image as inline styles, which only !important can override. */
.article-body > figure,
.article-body > .wp-block-image,
.article-body > .wp-block-gallery,
.article-body > .alignwide,
.article-body > .alignfull{grid-column:wide;margin-block:var(--s5)}
.article-body > figure + *,
.article-body > .wp-block-image + *{margin-top:0}
.article-body figure img{display:block;width:100% !important;height:auto !important;border-radius:var(--r) !important}
.article-body > .article-lead-image{margin-top:0}
.article-body > .article-lead-image img{aspect-ratio:16/9;object-fit:cover}
.article-body figcaption{font-size:.875rem;color:var(--ink-3);margin-top:10px;text-align:center}

.article-body h2{font-size:clamp(1.4rem,2.2vw,1.75rem);line-height:1.15;margin-top:var(--s5);color:var(--ink)}
/* Headings in running text use the whole column; the site-wide 22ch cap is for section titles. */
.article-body h2,.article-body h3{max-width:none}
.article-body h3{font-size:1.2rem;margin-top:var(--s4);color:var(--ink)}
.article-body h2 + *,.article-body h3 + *{margin-top:.75em}
.article-body a{color:var(--accent);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px}
.article-body a:hover{color:var(--ink)}
.article-body ul,.article-body ol{padding-left:1.4em}
.article-body li+li{margin-top:.4em}
.article-body blockquote{border-left:2px solid var(--accent);padding-left:var(--s3);font-size:1.25rem;color:var(--ink)}
.article-body strong{color:var(--ink);font-weight:600}
.article-body .aligncenter{margin-inline:auto;text-align:center}
.article-body .wp-caption-text{font-size:.875rem;color:var(--ink-3)}

@media (max-width:900px){
  /* Starts where the hero does on a phone, just under the taller header. */
  .article-page{padding-top:calc(var(--s5) + 20px)}
  .article-header{padding:var(--s4) var(--s3)}
  .article-header::before{background:
      radial-gradient(90% 60% at 80% 10%,rgba(253,242,216,.9),transparent 70%),
      linear-gradient(172deg,var(--cream) 0%,var(--cream) 45%,var(--rose) 85%,var(--taupe) 100%)}
  .article-header h1{font-size:clamp(1.75rem,7.4vw,2.4rem)}
  /* The side columns become the panel's own inner padding, so paragraphs line up
     with the title inside the header while photographs still reach its edges. */
  .article-body{padding-top:var(--s4);font-size:1.0625rem;line-height:1.75;
    grid-template-columns:[wide-start] var(--s3) [text-start] minmax(0,1fr) [text-end] var(--s3) [wide-end]}
  .article-body > p:first-child,
  .article-body > .article-lead-image + p{font-size:1.125rem}
  .article-body > figure,
  .article-body > .wp-block-image,
  .article-body > .wp-block-gallery,
  .article-body > .alignwide,
  .article-body > .alignfull{margin-block:var(--s4)}
}

/* -------- blog index (index.php / home.php) -------- */
/* The archive wears the article page's header panel and wide width (the
   --article-* sizes come from .article-page), with the front page's cards. */
.archive-list{width:min(100% - 2.5rem,var(--article-wide));margin-inline:auto;
  padding:var(--s5) 0 calc(var(--section-space) / 2)}
.archive-list .post-grid{grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.archive-empty{color:var(--ink-2)}

/* "Zobacz wszystkie" under the four newest articles on the front page. */
.articles-all{display:flex;justify-content:center;margin-top:var(--s4)}
.pagination{display:flex;gap:12px;justify-content:center;margin-top:var(--s5)}
.pagination .page-numbers{padding:10px 16px;border-radius:999px;font-size:.9375rem;
  font-weight:600;color:var(--ink-2);box-shadow:inset 0 0 0 1px var(--line)}
.pagination .current{background:var(--btn);color:#fff;box-shadow:none}

/* -------- map (replaces the Google Maps iframe on the contact page) -------- */
.map-link{display:block;border-radius:14px;overflow:hidden;margin-top:var(--s3);
  position:relative;background:var(--cream-2)}
.map-link img{width:100%;aspect-ratio:16/10;object-fit:cover}

/* -------- 404 -------- */
.not-found{padding:calc(var(--s6) + 20px) 0 var(--s3);text-align:center}
.not-found p{color:var(--ink-2);max-width:46ch;margin:var(--s3) auto 0}
.not-found .button{margin-top:var(--s4)}

/* -------- UV section with no daylight photograph yet --------
   The lamp is inert until the second frame exists, so it must not hide the
   cursor or paint a mask hole over a single image. */
.uv-lamp-disabled{cursor:auto!important}
.uv-lamp-disabled .daylight-layer,.uv-lamp-disabled .lamp-ring,.uv-lamp-disabled .lamp-hint{display:none!important}
@media (pointer:fine){
  .uv-lamp-disabled{cursor:auto}
  .uv-lamp-disabled .uv-layer{-webkit-mask-image:none;mask-image:none}
}

/* The post-card link uses the same inline arrow as the buttons, because
   U+2192 is not in either Figtree subset and would fall back mid-sentence. */
.post-card .post-card-more{display:inline-flex;align-items:center;gap:8px}
.post-card .post-card-more svg{width:15px;height:15px;transition:transform .45s var(--ease)}
.post-card:hover .post-card-more svg{transform:translateX(4px)}

/* =========================================================================
   4. Navigation, layout and gallery.
   ========================================================================= */

/* -------- the footer sits at the bottom on short pages -------- */
body{display:flex;flex-direction:column;min-height:100vh;min-height:100svh}
main{flex:1 0 auto}
footer{flex-shrink:0;margin-top:auto}

/* -------- footer (footer.php) --------
   One compact block: copyright and legal name with the credit beneath it on
   the left, the privacy policy and cookie settings on the right, level with
   them. On a phone everything stacks.
   Nothing sits in the bottom-right corner, where the GTranslate language
   switcher floats, so the padding can stay tight. */
.site-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--s2) var(--s4);padding:var(--s4) 0}
.site-footer-info{display:grid;gap:4px}
.site-footer-links{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s4)}

/* "Ustawienia cookies" opens the banner rather than going anywhere, so it is a
   button, dressed to match the link beside it. The underline appears on hover. */
.site-footer-links a,
.site-footer-button{font:inherit;font-weight:500;color:var(--ink-2);
  background:none;border:0;padding:0;cursor:pointer;
  text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:1px;
  text-underline-offset:4px;transition:color .35s var(--ease),text-decoration-color .35s var(--ease)}
.site-footer-links a:hover,
.site-footer-button:hover{color:var(--ink);text-decoration-color:currentColor}

.site-footer-credit{font-size:.8125rem}
.site-footer-credit a{color:var(--ink-2);text-decoration:underline;text-decoration-color:var(--line-2);
  text-decoration-thickness:1px;text-underline-offset:3px;
  transition:color .35s var(--ease),text-decoration-color .35s var(--ease)}
.site-footer-credit a:hover{color:var(--accent);text-decoration-color:currentColor}

@media (max-width:600px){
  .site-footer{flex-direction:column;align-items:flex-start}
  /* On a phone the links come first, above the copyright and the credit. */
  .site-footer-links{order:-1}
}

/* -------- cookie consent banner (inc/consent.php) --------
   A card in the corner rather than a bar across the page, so it never covers
   the hero's headline. Both answers are the same size: refusing is as easy as
   agreeing. On a phone it spans the width, just above the bottom edge.
   The very high z-index keeps it above the GTranslate language switcher, which
   floats in the same corner with its own high z-index; the switcher is usable
   again as soon as the visitor has answered. */
.consent-banner{position:fixed;z-index:1000000;left:var(--s3);bottom:var(--s3);
  width:min(100% - 2 * var(--s3),26rem);padding:var(--s3);
  background:var(--white);color:var(--ink);border-radius:var(--r);
  box-shadow:0 0 0 1px var(--line),0 24px 48px rgba(15,23,41,.14);
  opacity:0;transform:translateY(12px);transition:opacity .35s var(--ease),transform .35s var(--ease)}
.consent-banner.is-visible{opacity:1;transform:none}
.consent-banner-title{margin:0;font-size:var(--micro);font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent)}
.consent-banner-text{margin:10px 0 0;font-size:.9375rem;line-height:1.6;color:var(--ink-2)}
.consent-banner-text a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.consent-banner-actions{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:var(--s3)}
.consent-banner .button{justify-content:center;padding:12px 16px;border:0;cursor:pointer;
  font-family:inherit;font-size:.9375rem}
@media (max-width:520px){
  .consent-banner{left:12px;right:12px;bottom:12px;width:auto}
}

/* -------- current section in the nav -------- */
nav a.is-current-section{color:var(--ink)}
nav a.is-current-section::after{transform:scaleX(1);transform-origin:left}

/* -------- mobile menu toggle (.menu-toggle) -------- */
.menu-toggle{display:none;width:44px;height:44px;padding:11px 9px;border:0;background:none;
  cursor:pointer;position:relative;z-index:830}
.menu-toggle span{display:block;height:2px;border-radius:2px;background:var(--ink);
  transition:transform .4s var(--ease),opacity .25s var(--ease)}
.menu-toggle span+span{margin-top:5px}
.menu-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.menu-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.menu-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

.menu-scrim{position:fixed;inset:0;z-index:790;background:rgba(15,23,41,.35);
  opacity:0;transition:opacity .4s var(--ease)}
.menu-scrim.is-visible{opacity:1}

/* -------- horizontal rails (museum photos, blog cards) -------- */
.rail-controls{display:flex;align-items:center;justify-content:center;gap:var(--s3);
  margin-top:var(--s3)}
.rail-controls[hidden]{display:none}
.rail-arrow{width:44px;height:44px;border:0;border-radius:50%;cursor:pointer;
  background:var(--cream-2);color:var(--ink);display:grid;place-items:center;
  transition:background .35s var(--ease)}
.rail-arrow svg{width:18px;height:18px}
.rail-arrow:hover{background:var(--cream)}
.rail-arrow:disabled{opacity:.35;cursor:default}
.rail-dots{display:flex;gap:8px}
.rail-dots button{width:8px;height:8px;padding:0;border:0;border-radius:50%;cursor:pointer;
  background:var(--line-2);transition:background .35s var(--ease),transform .35s var(--ease)}
.rail-dots button[aria-current="true"]{background:var(--accent);transform:scale(1.35)}

/* -------- stacked section head -------- */
.section-head-stacked{display:block}
.section-head-stacked h2,.section-head-stacked h1{max-width:22ch}
.section-head-stacked > p{margin-top:var(--s3)}

/* -------- UV card and quote share one row --------
   Two thirds to the lamp card, one third to the quote. Inside the card the
   copy sits beside the photograph so the card stays about 460px tall rather
   than the ~900px a full-width lamp produced. */
.uv-lamp-row{display:grid;gap:var(--s3)}
.uv-lamp-row > :only-child{grid-column:1/-1}
.uv-lamp-row .owners-quote{display:grid;align-content:center;margin:0}

@media (min-width:901px){
  .uv-lamp-row{grid-template-columns:minmax(0,2fr) minmax(0,1fr);align-items:stretch}
  .uv-lamp-card{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,300px);
    gap:clamp(1.5rem,3vw,2.75rem);align-items:center}
  .uv-lamp-copy > p{margin-top:14px;margin-bottom:0}
  .uv-lamp{aspect-ratio:4/5}
  .uv-lamp-row .owners-quote blockquote{font-size:clamp(1.15rem,1.5vw,1.5rem);max-width:22ch}
  .uv-lamp-row .owners-quote{padding:clamp(2rem,3vw,3rem) var(--s3)}
}

@media (max-width:900px){
  .menu-toggle{display:block}

  nav{position:fixed;left:0;right:0;top:0;z-index:820;padding:92px 0 32px;
    background:var(--white);box-shadow:0 24px 48px rgba(15,23,41,.12);
    transform:translateY(-101%);transition:transform .5s var(--ease);
    visibility:hidden}
  nav[data-menu-open="true"]{transform:none;visibility:visible}

  nav ul{flex-direction:column;gap:0;width:min(100% - 2.5rem,var(--page-width));margin-inline:auto}
  nav li{border-top:1px solid var(--line)}
  nav li:last-child{border-bottom:1px solid var(--line)}
  nav a{display:block;padding:17px 0;font-size:1.0625rem;font-weight:600;color:var(--ink)}
  nav a::after{display:none}
  nav a.is-current-section{color:var(--accent)}

  /* Both rails go one item at a time and snap. */
  .case-rail{scroll-snap-type:x mandatory}
  .case-rail figure{flex:0 0 100%;scroll-snap-align:center}
}

@media (prefers-reduced-motion:reduce){
  .case-rail,.post-rail-wrap .post-grid{scroll-behavior:auto}
  nav{transition:none}
}

/* =========================================================================
   5. Hero (.hero), from template-parts/hero.php.

   One gradient panel carrying the headline and the specimen, then the ticker,
   then a single line of practical facts. The panel, its two light layers and
   the grain are the approved prototype's. The facts line replaces the tiles
   and the large counters, which is what lets the ticker and the facts sit on
   the first screen.

   Desktop height (901px and wider). The hero fills the first screen and
   centres its content in the space below the fixed header, so the gap above
   the panel always matches the gap below the facts line. Two things make that
   work on every window size:

     short windows  the panel's vertical padding, the space above the buttons
                    and the headline all scale with the window height (vh), so
                    a 13" laptop with the browser not maximised still fits the
                    facts line on the first screen
     tall windows   the extra height is split equally above and below; the
                    hero stops growing at 1200px so a very tall monitor does
                    not strand it in a sea of empty space

   Phones and tablets keep a plain top and bottom padding instead.
   ========================================================================= */
.hero-panel{position:relative;isolation:isolate;overflow:hidden;border-radius:var(--r);
  background:linear-gradient(108deg,var(--cream) 0%,var(--cream) 36%,var(--rose) 68%,var(--taupe) 100%)}

/* A warm highlight that drifts slowly behind the specimen. */
.specimen-glow{position:absolute;inset:-20%;z-index:0;pointer-events:none;
  background:radial-gradient(38% 46% at 74% 32%,rgba(253,242,216,.95),transparent 64%),
             radial-gradient(34% 40% at 96% 86%,rgba(102,84,82,.7),transparent 70%);
  animation:drift 22s ease-in-out infinite alternate}
@keyframes drift{0%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(-2.5%,1.5%,0) scale(1.06)}
  100%{transform:translate3d(1.5%,-2%,0) scale(1.02)}}

/* A soft band of light that crosses the panel every ten seconds. */
.specimen-sweep{position:absolute;top:0;bottom:0;width:34%;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.5),transparent);
  filter:blur(18px);animation:sweep 10s var(--ease) infinite;opacity:.7}
@keyframes sweep{0%{left:-40%}55%,100%{left:120%}}

/* Faint grain over everything, so the gradient does not band on large screens. */
.hero-panel::after,.article-header::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:multiply}

.hero-panel-inner{position:relative;z-index:2;display:grid;
  grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);align-items:center;
  gap:var(--s4);padding:clamp(2rem,4.5vw,4rem)}
.hero-copy h1{margin-top:14px;font-size:clamp(2.2rem,4.2vw,3.75rem);line-height:1.02}
.hero-lead{max-width:48ch;margin-top:var(--s3);color:#3E4149;font-size:1.0625rem}
.hero-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s4);margin-top:var(--s4)}
.hero-uv-link{font-size:.9375rem;font-weight:500;color:var(--ink);padding-bottom:3px;
  border-bottom:1px solid var(--line-2);transition:color .35s var(--ease),border-color .35s var(--ease)}
.hero-uv-link:hover{color:var(--accent);border-color:var(--accent)}

.hero-specimen{justify-self:center;will-change:transform}
.hero-specimen img{width:min(100%,460px);filter:drop-shadow(0 30px 50px rgba(83,64,62,.3))}

/* -------- the facts line under the ticker -------- */
.hero-facts{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:10px var(--s4);padding:16px 0;font-size:.875rem;color:var(--ink-2)}
/* Figures on the left on desktop, although they come second in the markup. */
.hero-stats{order:-1;display:flex;flex-wrap:wrap;gap:6px var(--s3);list-style:none;margin:0;padding:0}
.hero-stats b{font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;margin-right:.25em}
.hero-visit-info{display:flex;flex-wrap:wrap;align-items:center;gap:6px var(--s4);margin:0;
  font-variant-numeric:tabular-nums}
.hero-today{display:inline-flex;align-items:center;gap:8px}
.hero-today::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ink-3);flex:0 0 auto}

@media (min-width:901px){
  .hero{
    /* Smallest gap kept above and below the hero content, grows with the window. */
    --hero-gap:clamp(.75rem,3vh,3rem);
    display:flex;flex-direction:column;justify-content:center;
    min-height:min(100vh,1200px);min-height:min(100svh,1200px);
    padding:calc(var(--header-height) + var(--hero-gap)) 0 var(--hero-gap)}
  /* The WordPress toolbar, shown to logged-in editors, takes 32px off the top. */
  .admin-bar .hero{min-height:min(calc(100vh - 32px),1200px);min-height:min(calc(100svh - 32px),1200px)}

  .hero-panel-inner{padding-block:clamp(1.75rem,7vh - 1.25rem,4.5rem)}
  .hero-copy h1{font-size:clamp(2.2rem,min(4.2vw,7.4vh),3.75rem)}
  .hero-actions{margin-top:clamp(1.5rem,4.5vh - .5rem,2.5rem)}
}

@media (max-width:900px){
  /* Top to bottom rather than left to right, so the warm end sits under the button. */
  .hero-panel{background:linear-gradient(172deg,var(--cream) 0%,var(--cream) 38%,var(--rose) 82%,var(--taupe) 100%)}
  .hero-panel-inner{grid-template-columns:1fr;padding:var(--s3)}
  .hero-copy h1{font-size:clamp(1.9rem,8.6vw,2.6rem)}
  .hero-specimen,.hero-uv-link{display:none}
  .hero-actions .button{width:100%;justify-content:center}

  .hero-facts{flex-direction:column;align-items:flex-start;gap:8px}
  .hero-stats{order:0}
  /* Hours and price read as one sentence: "Dziś otwarte … · bilet 18 / 14 zł". */
  .hero-visit-info{gap:0}
  .hero-today + .hero-ticket::before{content:"·";margin:0 .45em}
  .hero-ticket-label{text-transform:lowercase}
}

/* =========================================================================
   6. Remarks from review.
   ========================================================================= */

/* Blog cards become a rail below the desktop breakpoint. */
@media (max-width:1024px){
  .post-rail-wrap .post-grid{display:flex;grid-template-columns:none;gap:var(--s3);
    overflow-x:auto;scroll-behavior:smooth;
    scrollbar-width:none;-ms-overflow-style:none}
  .post-rail-wrap .post-grid::-webkit-scrollbar{display:none}
  .post-rail-wrap .post-card{flex:0 0 min(78%,320px)}
  /* The lift on hover would clip inside a scroller. */
  .post-rail-wrap .post-card:hover{transform:none}
}

/* The store photograph is dropped on narrow screens: the section already runs
   long there and the picture adds most of its height. */
@media (max-width:900px){
  #sklep > .feature-row:first-of-type > img{display:none}
}
