/* ==========================================================================
   Piren — component styles, part 1: the chrome that wraps every page.

   WHY THESE ARE NOT IN components/<name>/<name>.css

   A co-located component stylesheet is bundled by the DEPLOY into
   assets/wl-components.<hash>.css and linked into the published HTML. That
   file does not exist in the source repo, so anything that renders the source
   — the Weblooks editor canvas — loads none of it. The site was correct on
   staging and completely unstyled in the editor.

   Moving the rules here was not enough on its own: layout.css pulled them in
   with @import, and the deploy neither rewrites @import targets nor publishes
   the unhashed files they name, so on staging the imports 404'd and only the
   co-located copies applied. Every page now carries real <link> tags instead,
   which the deploy content-hashes like any other stylesheet.

   With that in place the co-located files were deleted. This file and
   sections.css are the only source of component CSS — there is no second copy
   to drift out of step. (Component .js files are still co-located: the deploy
   links that bundle into the published HTML, so it has no editor problem.)

   Nothing here is scoped, so class names carry the whole burden of not
   colliding. Every rule is BEM under a component's own block name; keep it
   that way.

   COMPONENT ROOTS LIVE IN layout.css, written as [data-wl-component="…"].
   They are duplicated there because the breakpoint tiers need something to
   override, and they must be read last to win.

   TEXT MEASURES come from the `ch` scale in layout.css — --measure-tight,
   --measure-short, --measure-prose, --measure-wide. Never a bare number.
   ========================================================================== */

/* ==========================================================================
   site-header — announcement band, wordmark, nav, booking CTA, mobile drawer.

   BREAKPOINTS LIVE IN layout.css, in the three `@container page` blocks. A
   @container rule cannot restyle the element that ESTABLISHES that container,
   and .site-header is `header`, so a breakpoint written here could only ever
   reach its descendants.
   ========================================================================== */

.site-header{
  position:relative;
  z-index:var(--layer-header);
  display:flex;
  flex-direction:column;
  align-items:stretch;
  background:var(--surface-page);
  color:var(--text-body);
  font-family:var(--font-body);
  font-size:var(--type-body);
  font-weight:var(--font-body-regular);

  container-type:inline-size;
  container-name:header;

  --desk:flex;
  --burger:none;
  --drawer:none;
  --announce-note:inline;
  --bar-gutter:var(--space-tight);
  --logo-max:clamp(3rem, 2.43rem + 2.86cqi, 5rem);
  --mega-cols:repeat(3, 1fr);
  --nav-card-w:14rem;
  --burger-icon:62%;
}

/* --- Announcement band ---------------------------------------------------- */
.site-header__announce{
  display:block;
  background:var(--color-secondary-950);
  color:var(--text-on-dark);
  text-decoration:none;
  transition:background-color var(--duration-medium) var(--ease-emphasis);
}
.site-header__announce:hover{background:var(--piren-slate);color:var(--text-on-dark)}

.site-header__announce-inner{
  display:flex;
  flex-flow:row wrap;
  justify-content:center;
  align-items:center;
  gap:0 1.2ch;
  inline-size:100%;
  max-inline-size:var(--max-width-main);
  margin-inline:auto;
  padding:.6em var(--bar-gutter);
  font-size:var(--type-xs);
  letter-spacing:var(--letter-spacing-eyebrow);
  text-transform:uppercase;
  text-align:center;
}
.site-header__diamond{
  inline-size:.4em;block-size:.4em;flex:none;
  background:currentColor;transform:rotate(45deg);
}
.site-header__announce-title{font-weight:var(--font-body-medium)}
/* The note is the least load-bearing part of the band; on a phone it is what
   turns one line into three, so layout.css drops it at the 48rem tier. */
.site-header__announce-note{display:var(--announce-note);opacity:.78}
.site-header__announce-cta{
  display:flex;align-items:center;gap:.7ch;
  font-weight:var(--font-body-medium);
}
.site-header__chevron{
  inline-size:.32em;block-size:.32em;flex:none;
  border-inline-end:.1em solid currentColor;
  border-block-start:.1em solid currentColor;
  transform:rotate(45deg);
}

/* --- Main bar -------------------------------------------------------------- */
.site-header__bar{
  display:flex;
  flex-flow:row nowrap;
  justify-content:space-between;
  align-items:center;
  gap:var(--space-tight);
  inline-size:100%;
  max-inline-size:var(--max-width-main);
  margin-inline:auto;
  padding:var(--space-hair) var(--bar-gutter);
}

/* --- Wordmark ----------------------------------------------------------------
   The static SVG is what paints, what carries the alt text, and what stays if
   the animation never arrives; the animated version renders into an overlay of
   the SAME box and only becomes visible once it has actually drawn. */
.site-header__logo{
  position:relative;
  flex:none;
  display:block;
  inline-size:100%;
  max-inline-size:var(--logo-max);
}
.site-header__logo-mark{inline-size:100%;block-size:auto;display:block}
.site-header__logo-anim{display:none}
/* visibility, not display: the static mark keeps reserving the space it had. */
.site-header__logo.is-animated .site-header__logo-mark{visibility:hidden}
.site-header__logo.is-animated .site-header__logo-anim{
  display:block;
  position:absolute;
  inset:0;
}
.site-header__logo-anim svg{inline-size:100%;block-size:100%;display:block}

/* THE ANIMATION IS EXPORTED IN PIREN'S TEAL (#00b6a8); the static mark beside
   it is slate (#3b495b, --piren-slate). So the hand-off from one to the other
   was a colour change as much as a swap, which is what made it read as a
   flicker rather than as the same mark coming to life. Painting the rendered
   paths from the same token the static SVG uses makes the two identical, and
   ties them together so they cannot drift apart again.

   A CSS `fill` already beats the presentation attribute lottie-web writes onto
   each path, so this works without !important today; !important additionally
   covers a future export that ANIMATES the colour, where lottie switches to
   writing an inline style instead. Paths explicitly set to `none` are strokes
   or masks and are left alone. */
.site-header__logo-anim svg path:not([fill="none"]){
  fill:var(--piren-slate) !important;
}

/* --- Desktop nav ----------------------------------------------------------- */
.site-header__nav{flex:1;display:var(--desk)}

.nav-list{
  display:flex;
  flex-flow:row wrap;
  justify-content:center;
  align-items:center;
  gap:var(--space-hair);
  inline-size:100%;
}

.nav-item{
  position:relative;
  transition:opacity var(--duration-medium) var(--ease-emphasis);
}
/* Dim the siblings of whatever the visitor is pointing at or tabbing to.
   .78 is the lowest opacity that still clears 4.5:1 ink-on-cream. */
.nav-list:hover       .nav-item:not(:hover),
.nav-list:focus-within .nav-item:not(:focus-within){opacity:.78}

.nav-item__link{
  display:flex;
  align-items:center;
  gap:.7ch;
  padding:var(--space-hair);
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  text-decoration:none;
}
.site-header[data-nav-active="menyer"] .nav-item[data-nav-id="menyer"] .nav-item__link,
.site-header[data-nav-active="julbord"] .nav-item[data-nav-id="julbord"] .nav-item__link,
.site-header[data-nav-active="abonnera"] .nav-item[data-nav-id="abonnera"] .nav-item__link,
.site-header[data-nav-active="evenemang"] .nav-item[data-nav-id="evenemang"] .nav-item__link,
.site-header[data-nav-active="hitta"] .nav-item[data-nav-id="hitta"] .nav-item__link,
.nav-item__link[aria-current="page"]{
  text-decoration:underline;
  text-underline-offset:.3em;
}

.nav-item__caret{
  inline-size:.3em;block-size:.3em;flex:none;
  border-inline-end:.1em solid currentColor;
  border-block-end:.1em solid currentColor;
  transform:rotate(45deg);
  transition:transform var(--duration-medium) var(--ease-emphasis);
}
.nav-item--has-menu:hover .nav-item__caret,
.nav-item--has-menu:focus-within .nav-item__caret{transform:rotate(-135deg)}

/* --- The full-width nav panel -------------------------------------------------
   position:static on the item hands the panel's containing block up to
   .site-header, which is the full width of the screen. That is the whole
   trick: the panel then spans edge to edge while its CONTENTS stay on the
   same 90rem column as the rest of the site.

   inset-block-start:100% is 100% of the header — announcement band plus bar —
   so the panel hangs directly below it, whatever the band is doing.

   It opens on hover AND on focus-within, so it is reachable by keyboard with
   no script at all. */
.nav-item--has-menu{position:static}

.nav-submenu{
  position:absolute;
  inset-block-start:100%;
  inset-inline:0;
  z-index:var(--layer-dropdown);
  background:var(--surface-page);
  border-block-end:var(--border-width-main) solid var(--text-heading);
  opacity:0;
  visibility:hidden;
  transform:translateY(-0.5rem);
  transition:opacity var(--duration-medium) var(--ease-emphasis),
             transform var(--duration-medium) var(--ease-emphasis),
             visibility var(--duration-medium);
}
.nav-item--has-menu:hover .nav-submenu,
.nav-item--has-menu:focus-within .nav-submenu{
  opacity:1;
  visibility:visible;
  transform:translateY(0);
}

.nav-submenu__inner{
  inline-size:100%;
  max-inline-size:var(--max-width-main);
  margin-inline:auto;
  padding:var(--space-snug) var(--bar-gutter);
  display:grid;
  grid-template-columns:var(--mega-cols);
  gap:var(--space-tight);
}

/* Each card is its own query container, so whether the words sit beside the
   picture or under it is decided from the width THAT CARD has rather than
   from the width of the window. */
.nav-submenu__item{
  container-type:inline-size;
  container-name:navcard;
}

.nav-card{
  display:flex;
  flex-direction:row;
  align-items:flex-start;
  gap:var(--space-tight);
  text-decoration:none;
  --zoom:1;
}
.nav-card:hover,
.nav-card:focus-visible{--zoom:1.06}

/* 45% keeps the picture and the words in proportion as the card resizes, and
   --nav-card-w stops it growing past half a wide column.

   The photograph is taken OUT OF FLOW, the way .media-frame does it. In flow,
   an <img> whose block-size:100% cannot resolve — the frame's own height comes
   from aspect-ratio, so the percentage is against an indefinite height — falls
   back to `auto` and renders at its intrinsic 2:3, which then stretches the
   frame past the 4:3 box it was asked to keep. Absolute positioning against a
   definite frame removes the cycle. */
.nav-card__frame{
  position:relative;
  flex:none;
  display:block;
  inline-size:min(45%, var(--nav-card-w));
  aspect-ratio:4/3;
  overflow:clip;
  background:var(--piren-sage);
}
.nav-card__img{
  position:absolute;
  inset:0;
  inline-size:100%;
  block-size:100%;
  object-fit:cover;
  display:block;
  transform:scale(var(--zoom));
  transition:transform var(--duration-fast) var(--ease-exit);
}

/* min-inline-size:0 so a long unbroken word cannot push the column wider than
   its share and shove the picture out of the card. */
.nav-card__body{
  flex:1;
  min-inline-size:0;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.2rem;
}
/* One step down from the h4 these used to take: inside a panel the page name
   is a label, not a heading competing with the page's own. */
.nav-card__name{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-md);
  line-height:var(--line-height-snug);
  color:var(--text-heading);
}
.nav-card__text{
  max-inline-size:var(--measure-tight);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}

/* Below 20rem the words get under ~18 characters a line beside the picture,
   which is where a description stops being readable and starts being a
   column of fragments. Put them under it instead and let both have the full
   width. */
@container navcard (max-width: 20rem){
  .nav-card{flex-direction:column}
  .nav-card__frame{inline-size:100%}
}

/* --- Actions ---------------------------------------------------------------- */
.site-header__actions{
  display:var(--desk);
  justify-content:flex-start;
  align-items:center;
  gap:var(--space-tight);
}

/* The phone's language switch, beside the burger rather than at the foot of
   the drawer: changing language is not a navigation choice and should not be
   behind a menu. It rides the SAME --burger flag as the burger itself, so the
   two appear and disappear together and can never disagree.

   margin-inline-start:auto is what keeps the pair together. The bar is
   justify-content:space-between, so with three visible children — wordmark,
   switch, burger — the switch would otherwise be stranded in the middle. */
.site-header__bar-lang{
  display:var(--burger);
  align-items:center;
  margin-inline-start:auto;
}

/* --- Burger ------------------------------------------------------------------
   Piren's three-wave mark, inlined so its strokes take currentColor. Opening
   cross-fades the waves out and a plain cross in, so the control still reads
   as "close" rather than repeating the open affordance.

   THE BUTTON AND THE MARK ARE SIZED SEPARATELY. The mark was drawn at the
   full size of its button and read as oversized next to the wordmark; the
   button itself has to stay around 44px or it stops being a comfortable
   thing to hit with a thumb. So the box keeps its tap target and
   --burger-icon shrinks only what is painted inside it.                     */
.site-header__burger{
  display:var(--burger);
  position:relative;
  flex:none;
  align-items:center;
  justify-content:center;
  inline-size:2.75em;
  block-size:2.75em;
  color:var(--text-heading);
}
.site-header__burger-icon{
  inline-size:var(--burger-icon);
  block-size:var(--burger-icon);
  transition:opacity var(--duration-fast) var(--ease-emphasis),
             transform var(--duration-medium) var(--ease-emphasis);
}
.site-header__burger[aria-expanded="true"] .site-header__burger-icon{
  opacity:0;
  transform:scale(.85);
}
/* The close cross is drawn to the same visual width as the waves above. */
.site-header__burger::before,
.site-header__burger::after{
  content:"";
  position:absolute;
  inset-inline:31%;
  block-size:var(--border-width-main);
  background:currentColor;
  opacity:0;
  transform:rotate(0deg) scale(.85);
  transition:opacity var(--duration-fast) var(--ease-emphasis),
             transform var(--duration-medium) var(--ease-emphasis);
}
.site-header__burger[aria-expanded="true"]::before{opacity:1;transform:rotate(45deg) scale(1)}
.site-header__burger[aria-expanded="true"]::after {opacity:1;transform:rotate(-45deg) scale(1)}

/* --- Drawer -------------------------------------------------------------------
   ABSOLUTELY POSITIONED, so opening the menu lays it OVER the page instead of
   pushing every section down the screen — which on a phone meant the whole
   article jumped as you tapped. Same trick as the nav panel above: the header
   is position:relative, and inset-block-start:100% puts this directly beneath
   it, announcement band included.

   Out of flow it no longer inherits a painted ground, so it carries its own —
   without a background the page would read straight through the menu.

   visibility:hidden when closed keeps the links out of the tab order; a
   max-height-only drawer would leave them focusable behind the fold. */
.site-header__drawer{
  display:var(--drawer);
  position:absolute;
  inset-block-start:100%;
  inset-inline:0;
  z-index:var(--layer-dropdown);
  overflow:clip;
  background:var(--surface-page);
  border-block-start:var(--border-width-main) solid var(--surface-tint);
  border-block-end:var(--border-width-main) solid var(--text-heading);
  transition:max-block-size var(--duration-slow) var(--ease-emphasis),
             opacity var(--duration-medium) var(--ease-emphasis),
             visibility var(--duration-medium);
}
.site-header__drawer[data-open="false"]{max-block-size:0;opacity:0;visibility:hidden;border-block-width:0}
/* 48rem clears six items, the submenu and the booking button at the largest
   step of the fluid type ramp. */
.site-header__drawer[data-open="true"] {max-block-size:48rem;opacity:1;visibility:visible}

.site-header__drawer-inner{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-tight);
  padding:var(--space-tight) var(--bar-gutter);
}
/* No rules between the items: the list is six words on a plain ground, and
   the dividers were doing more work than the spacing needed. */
.drawer-list{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-hair);
}
.drawer-item{
  display:flex;
  flex-direction:column;
  align-items:stretch;
}
.drawer-item__link{
  display:block;
  padding:.35em 0;
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-body-lg);
  text-decoration:none;
}
.drawer-item__link[aria-current="page"]{text-decoration:underline;text-underline-offset:.3em}
.drawer-sublist{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.5em;
  padding:.2em 0 .6em 1.2em;
}
.drawer-sublist li{display:flex;align-items:center;gap:.8ch}
.drawer-sublist__mark{
  inline-size:.32em;block-size:.32em;flex:none;
  border:var(--border-width-main) solid var(--color-secondary-400);
  transform:rotate(45deg);
}
.drawer-sublist a{font-size:var(--type-body);text-decoration:none}

/* ==========================================================================
   lang-switch — SV / EN
   ========================================================================== */

.lang-switch{
  display:flex;
  align-items:center;
  gap:.6ch;
  font-size:var(--type-xs);
  letter-spacing:var(--letter-spacing-wide);
}
/* In the drawer it is the last thing on the panel rather than a bar item, so
   it centres and takes the drawer's larger text. */
.lang-switch--drawer{
  justify-content:center;
  padding-block-start:var(--space-hair);
  font-size:var(--type-sm);
}
.lang-switch__option{
  font-weight:var(--font-body-medium);
  text-decoration:none;
  transition:opacity var(--duration-medium) var(--ease-emphasis);
}
.lang-switch__option.is-current{text-decoration:underline;text-underline-offset:.3em}
/* Not a link — dimmed, but still above the 4.5:1 floor. */
.lang-switch__option.is-unavailable{opacity:.78;cursor:default}
.lang-switch__divider{
  inline-size:var(--border-width-main);
  block-size:.95em;
  background:currentColor;
  opacity:.4;
}

/* ==========================================================================
   site-footer — brand block, three link columns, legal notice.
   Runs on .piren-theme-inverse, so every colour comes from the flipped theme
   tokens rather than from hardcoded values.
   ========================================================================== */

.site-footer{
  position:relative;
  background:var(--piren-slate) var(--texture-foam) 50% / cover no-repeat;
  color:var(--text-body);
  font-family:var(--font-body);
  font-size:var(--type-body);
  font-weight:var(--font-body-regular);
  line-height:var(--line-height-normal);

  container-type:inline-size;
  container-name:footer;
}

.site-footer__inner{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  inline-size:100%;
  max-inline-size:var(--max-width-main);
  margin-inline:auto;
}

.site-footer__top{
  display:flex;
  flex-flow:row wrap;
  justify-content:flex-start;
  align-items:flex-start;
  gap:var(--space-column);
  padding:var(--section-y-sm) var(--space-tight);
}

.site-footer__brand{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
}
.site-footer__logo{
  display:block;
  flex:none;
  inline-size:100%;
  max-inline-size:var(--space-column);
  min-block-size:var(--space-snug);
}
.site-footer__logo img{inline-size:100%;block-size:auto}

.site-footer__address{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
}
.site-footer__address a{text-decoration:none}
.site-footer__address a:hover{text-decoration:underline;text-underline-offset:.18em}

.site-footer__nav{
  flex:1;
  inline-size:100%;
  min-inline-size:min(100%, 28rem);
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:stretch;
  gap:var(--space-tight);
}
.site-footer__list{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
}
.site-footer__list a{text-decoration:none}
.site-footer__list a:hover{text-decoration:underline;text-underline-offset:.18em}

.site-footer__legal{
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:flex-start;
  gap:var(--space-hair);
  padding:var(--space-hair) var(--space-tight) var(--space-tight);
}
.site-footer__copyright{
  max-inline-size:none;
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  /* The design dims this to 50%. That lands at 3.4:1 on slate — .7 is the
     lowest value that still clears 4.5:1. */
  opacity:.7;
}
.site-footer__policy{
  display:flex;
  flex-flow:row wrap;
  justify-content:flex-start;
  align-items:center;
  gap:var(--space-tight);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
}
.site-footer__policy a{text-decoration:none}
.site-footer__policy a:hover{text-decoration:underline;text-underline-offset:.18em}

/* A button because it opens a dialog rather than going anywhere, styled as
   the links beside it so the row reads as one set. */
.site-footer__consent-link{
  padding:0;
  border:0;
  background:none;
  color:inherit;
  font:inherit;
  cursor:pointer;
  text-decoration:none;
}
.site-footer__consent-link:hover{text-decoration:underline;text-underline-offset:.18em}

/* When the footer is narrow, the three link columns become one stack under
   the brand block instead of squeezing into unreadable slivers. */
@container footer (max-width: 44rem){
  .site-footer__top{gap:var(--space-snug)}
  .site-footer__nav{
    flex-direction:column;
    gap:var(--space-snug);
    min-inline-size:100%;
  }
  .site-footer__legal{flex-direction:column}
}

/* ==========================================================================
   cookie-consent — the notice, and the dialog behind "Anpassa".

   The root is position:fixed (set in layout.css) and hidden until
   cookie-consent.js decides there is a question to ask, so on a return visit
   it costs the page nothing but the markup.
   ========================================================================== */

.cookie-consent[hidden],
.cookie-consent__bar[hidden],
.cookie-modal[hidden]{display:none}

/* Full width, sitting on the bottom edge. A bar rather than a centred modal:
   the notice should be answerable without being in the way of the page it is
   asking about. */
.cookie-consent__bar{
  background:var(--surface-page);
  border-block-start:var(--border-width-main) solid var(--text-heading);
  color:var(--text-body);
}
.cookie-consent__inner{
  inline-size:100%;
  max-inline-size:var(--max-width-main);
  margin-inline:auto;
  padding:var(--space-tight);
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:center;
  gap:var(--space-tight);
}
.cookie-consent__copy{
  flex:1;
  min-inline-size:min(100%, 24rem);
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.2rem;
}
.cookie-consent__title{
  max-inline-size:none;
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h4);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}
.cookie-consent__text{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.cookie-consent__actions{
  display:flex;
  flex-flow:row wrap;
  align-items:center;
  gap:var(--space-hair);
}
/* On a phone the three buttons stack rather than shrinking to fit — a row of
   cramped targets is the worst possible thing to hand a thumb. */
@container page (max-width: 30rem){
  .cookie-consent__actions{inline-size:100%}
  .cookie-consent__actions .btn{flex:1;min-inline-size:100%}
}

/* --- The dialog ------------------------------------------------------------- */
.cookie-modal{
  position:fixed;
  inset:0;
  display:flex;
  align-items:center;
  justify-content:center;
  padding:var(--space-tight);
}
.cookie-modal__backdrop{
  position:absolute;
  inset:0;
  background:var(--surface-dark);
  opacity:.55;
}
.cookie-modal__panel{
  position:relative;
  inline-size:100%;
  max-inline-size:34rem;
  /* The panel scrolls, not the page behind it: on a short screen in landscape
     three categories plus the buttons do not fit, and a dialog you cannot
     reach the Save button in is a dead end. */
  max-block-size:85dvh;
  overflow-y:auto;
  padding:var(--space-snug);
  background:var(--surface-page);
  border:var(--border-width-main) solid var(--text-heading);
  display:flex;
  flex-direction:column;
  gap:var(--space-tight);
}
.cookie-modal__title{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h3);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}
.cookie-modal__text{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}

.cookie-modal__list{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-tight);
}
.cookie-option{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.2rem;
  padding-block-end:var(--space-tight);
  border-block-end:var(--border-width-main) solid var(--border-color-hairline);
}
.cookie-option:last-child{border-block-end:0;padding-block-end:0}
/* A real label wrapping a real checkbox: the whole name is the hit area and
   the state is announced without any help from script. */
.cookie-option__row{
  display:flex;
  align-items:center;
  gap:.8ch;
  cursor:pointer;
}
.cookie-option__input{
  inline-size:1.1em;
  block-size:1.1em;
  flex:none;
  accent-color:var(--piren-slate);
  cursor:pointer;
}
/* Necessary cookies cannot be switched off, and the control says so itself
   rather than only looking inert. */
.cookie-option__input:disabled{cursor:default;opacity:.6}
.cookie-option__name{
  font-weight:var(--font-body-medium);
  font-size:var(--type-md);
  color:var(--text-heading);
}
.cookie-option__text{
  max-inline-size:var(--measure-prose);
  padding-inline-start:calc(1.1em + .8ch);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}

.cookie-modal__actions{
  display:flex;
  flex-flow:row wrap;
  justify-content:flex-end;
  align-items:center;
  gap:var(--space-hair);
}

/* ==========================================================================
   hero-banner — a full-bleed photograph with no words on it.
   The spacer, not the image, sets the band's height, so the photo can be
   over-scaled and cropped without ever dictating layout. --hero-h is set on
   the root in layout.css, where the tiers shrink it on a phone and remove the
   band entirely on a small one — matching piren-bar.se.
   ========================================================================== */

.hero-banner{
  position:relative;
  overflow:clip;
  container-type:inline-size;
  container-name:hero;
  --hero-h:clamp(14rem, 30cqi, 24rem);
}

.hero-banner__spacer{
  inline-size:100%;
  max-inline-size:var(--max-width-main);
  margin-inline:auto;
  padding:var(--section-y-sm) var(--space-tight);
  min-block-size:var(--hero-h);
}

.hero-banner__image{
  position:absolute;
  inset:0;
  inline-size:100%;
  /* 110%: the section that follows lifts itself over the band, so the photo
     is grown past the spacer to keep the crop full-bleed. */
  block-size:110%;
  min-inline-size:100%;
  min-block-size:110%;
  object-fit:cover;
}

/* ==========================================================================
   intro-split — the portrait reel beside the page's one h1.
   The row lifts itself up over the hero band above it.
   ========================================================================== */

.intro-split{
  container-type:inline-size;
  container-name:intro;
}

.intro-split__row{
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:center;
  gap:var(--space-snug);
  /* Pulls the block up into the hero photograph. Percentage, so the overlap
     scales with the column rather than snapping at a breakpoint. The 48rem
     tier in layout.css zeroes this, because from there down the hero band is
     a 5.5rem strip or gone entirely. */
  margin-block-start:-15%;
}

.intro-split__media{
  inline-size:100%;
  max-inline-size:var(--tile);
  min-inline-size:var(--decor-min);
}

/* 50% is a share of the row, not a text measure — the two halves split it.
   The copy inside still takes its measure from the ch scale. */
.intro-split__copy{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
  max-inline-size:50%;
  min-inline-size:min(100%, 26rem);
}

.intro-split__heading{
  font-size:var(--type-h1);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}

.intro-split__lead{
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
  color:var(--text-heading);
}

.intro-split__cta{margin-block-start:var(--space-hair)}

/* Once the section itself is narrow the two halves stack, the copy takes the
   full width back, and the overlap with the hero shrinks so the heading does
   not ride up onto the photograph. The 78cqi cap holds the reel back from the
   gutters on a tablet; the 48rem page tier in layout.css lifts it to 100%,
   because on a phone a film inset inside its own column reads as a mistake. */
@container intro (max-width: 52rem){
  .intro-split__row{margin-block-start:-8%}
  .intro-split__copy{max-inline-size:100%}
  .intro-split__media{max-inline-size:min(78cqi, var(--tile))}
}

/* ==========================================================================
   media-split — a block of copy beside a square photo/video frame.
   ========================================================================== */

.media-split{
  container-type:inline-size;
  container-name:split;
}

.media-split--tint{
  background:var(--surface-tint) var(--texture-salt-lines) 50% / cover no-repeat;
}

/* The seasonal band. It flips the theme tokens wholesale rather than only the
   background, so the heading, the body copy, the button and any link inside
   re-skin together instead of each needing its own override. */
.media-split--julbord{
  background:var(--piren-brick) var(--texture-foam) 50% / cover no-repeat;
  color:var(--piren-cream);
  --text-body:var(--piren-cream);
  --text-heading:var(--piren-cream);
  --text-muted:var(--color-primary-200);
  --border-color:var(--piren-cream);
  --border-color-hairline:var(--color-primary-200);
  --button-bg:var(--piren-cream);
  --button-text:var(--color-secondary-900);
  --button-bg-hover:var(--color-primary-200);
  --button-text-hover:var(--color-secondary-900);
  --button-outline:var(--piren-cream);
  --link-color:var(--piren-cream);
  --link-color-hover:var(--color-primary-200);
  --focus-ring-color:var(--piren-cream);
  --focus-ring-offset:var(--piren-brick);
}

.media-split__row{
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:center;
  gap:var(--space-snug);
}

/* THE COLUMN IS THE MEASURE. base.css caps every <p> at --measure-prose,
   which inside an already-narrow column caps it twice: the paragraphs stopped
   ~15ch short of the column's right edge while the heading and the button ran
   to it, so the block looked ragged and arbitrarily narrow — most visibly on
   the Julbord band, where the brick ground makes the column's real extent
   plain. Capping the COLUMN and letting the text fill it gives heading, body
   and button one shared right edge. */
.media-split__copy{
  flex:1;
  min-inline-size:min(100%, 26rem);
  max-inline-size:var(--measure-wide);
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-tight);
}
.media-split__text{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
}
/* The body also carries .rich-text (see layout.css), which is what puts air
   between two paragraphs coming out of the slot. */
.media-split__body p{
  max-inline-size:none;
  line-height:var(--line-height-relaxed);
}

/* flex:1 alone let the frame take half the row — ~42rem of photograph at the
   90rem container, enough that the picture rather than the words became the
   section. --hero-max caps it about a fifth under that; --hero-w stays the
   floor at which the row wraps instead of squeezing. */
.media-split__media{
  flex:1;
  min-inline-size:min(100%, var(--hero-w));
  max-inline-size:var(--hero-max);
}

/* The frame leads. DOM order stays copy-then-media, so the heading is still
   the first thing a screen reader meets and the CTA keeps its tab position. */
.media-split--media-start .media-split__media{order:-1}

@container split (max-width: 44rem){
  .media-split__row{gap:var(--space-tight)}
}

/* ==========================================================================
   gallery-strip — a band of portrait shots that tracks the page scroll.
   A real scroll container rather than a transformed track, so the row stays
   reachable by keyboard, trackpad and touch with the motion switched off.
   ========================================================================== */

.gallery-strip{
  position:relative;
  inline-size:100%;
  padding-block:var(--space-snug);
  overflow-x:auto;
  overflow-y:hidden;
  scroll-behavior:auto;
  overscroll-behavior-x:contain;
  scrollbar-width:none;
  container-type:inline-size;
  container-name:strip;
  --tile-w:var(--element-min);
}
.gallery-strip::-webkit-scrollbar{display:none}

.gallery-strip__track{
  display:flex;
  justify-content:flex-start;
  align-items:center;
  gap:var(--space-snug);
  inline-size:max-content;
  padding-inline:var(--space-tight);
}

.gallery-strip__tile{
  position:relative;
  flex:none;
  inline-size:var(--tile-w);
  aspect-ratio:2/3;
  background:var(--color-accent-coral);
  overflow:clip;
}

.gallery-strip__image{
  position:absolute;
  inset:0;
  inline-size:100%;
  block-size:100%;
  object-fit:cover;
}

@container strip (max-width: 44rem){
  .gallery-strip__track{gap:var(--space-tight)}
}

/* ==========================================================================
   page-header — the opening statement on a subpage: the page's one h1 and an
   optional standfirst. Deliberately quiet, so the section that follows
   carries the weight.
   ========================================================================== */

.page-header__inner{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-hair);
  text-align:center;
}
.page-header__lead{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
}
/* No standfirst on this page — collapse rather than leave a phantom gap. */
.page-header__lead:empty{display:none}
