/* ==========================================================================
   Piren — component styles, part 2: the page sections.

   See components.css for why these are ordinary repo stylesheets rather than
   co-located components/<name>/<name>.css files. In short: the deploy bundles
   those into a file that does not exist in source, so the editor canvas loads
   none of them.

   Unscoped, 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.

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

/* ==========================================================================
   lunch-week — the five weekday boards.
   Each day is a flex column with a percentage floor, so the row reflows from
   5-up to 2-up to 1-up on its own; the floor is set in layout.css.
   ========================================================================== */

.lunch-week{
  container-type:inline-size;
  container-name:lunch;
  --day-floor:30%;
}

.lunch-week__inner{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:flex-start;
  gap:var(--space-loose);
}

.lunch-week__intro{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-hair);
  text-align:center;
}
.lunch-week__note{
  max-inline-size:var(--measure-prose);
  line-height:var(--line-height-relaxed);
}

.lunch-week__days{
  display:flex;
  flex-flow:row wrap;
  justify-content:center;
  align-items:flex-start;
  gap:var(--space-tight);
  inline-size:100%;
}

.lunch-day{
  flex:1;
  min-inline-size:var(--day-floor);
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-tight);
}
.lunch-day__name{
  font-size:var(--type-h4);
  line-height:var(--line-height-normal);
  text-align:center;
}
/* lunch-week.js marks one day as today's and hides the rest on the home page
   teaser. .lunch-day sets display:flex, which beats the UA default for
   [hidden] — without this rule the teaser shows all five days. */
.lunch-day[hidden]{display:none}

/* The surviving day is alone in the row, so it takes the full width and caps
   at a readable measure instead of sitting in a fifth-width column. */
.lunch-day--today{
  min-inline-size:100%;
  max-inline-size:var(--measure-prose);
}

.lunch-day__dishes{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-hair);
  inline-size:100%;
}

/* The day column is already narrow and centred, so it IS the measure — a
   second cap inside it would only pull the text off its own centre line. */
.lunch-week .dish{text-align:center}
.lunch-week .dish__name{
  max-inline-size:none;
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
  text-transform:uppercase;
  color:var(--text-heading);
}
/* A dish with no description would otherwise leave its gap in the stack. */
.lunch-week .dish__detail:empty{display:none}
.lunch-week .dish__detail p{
  max-inline-size:none;
  line-height:var(--line-height-relaxed);
}

.lunch-week .dish__detail{
  max-inline-size:none;
  line-height:var(--line-height-relaxed);
}

/* The two dishes served every day. lunch-week.js copies them into each
   weekday column; this list is the source it copies from. */
.lunch-week__allweek{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-tight);
  inline-size:100%;
  max-inline-size:var(--measure-prose);
  padding-block-start:var(--space-tight);
  border-block-start:var(--border-width-main) solid var(--border-color-hairline);
}

@container lunch (max-width: 44rem){
  .lunch-week__inner{gap:var(--space-snug)}
}

/* ==========================================================================
   menu-cards — three menu teasers.
   The grid is intrinsically responsive (auto-fit + a minmax floor), so it
   reflows without a single breakpoint; layout.css only tunes the floor.
   ========================================================================== */

.menu-cards{
  container-type:inline-size;
  container-name:menus;
  --card-floor:var(--element-xmin);
}

.menu-cards__inner{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:flex-start;
  gap:var(--space-snug);
}

.menu-cards__intro{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-hair);
  text-align:center;
}
.menu-cards__lead{
  max-inline-size:var(--measure-prose);
  line-height:var(--line-height-relaxed);
}

.menu-cards__grid{
  inline-size:100%;
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(var(--card-floor), 1fr));
  gap:var(--space-tight);
}

.menu-card{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--space-hair);
  text-decoration:none;
  --zoom:1;
}
.menu-card:hover,
.menu-card:focus-visible{--zoom:1.08}

.menu-card__title{
  position:relative;
  z-index:var(--layer-raised);
  font-size:var(--type-h3);
  line-height:var(--line-height-snug);
  text-align:center;
}

.menu-card__frame{
  display:block;
  overflow:clip;
  inline-size:100%;
}
.menu-card__image{
  inline-size:100%;
  block-size:auto;
  transform:scale(var(--zoom));
  transition:transform var(--duration-fast) var(--ease-exit);
}

.menu-cards__group{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  text-align:center;
}

@container menus (max-width: 44rem){
  .menu-cards__inner{gap:var(--space-tight)}
}

/* ==========================================================================
   find-us — directions, opening hours and the map.
   Hours are a description list (day to time) rather than a row of divs, so
   the pairing survives without sight of the layout.
   ========================================================================== */

.find-us{
  container-type:inline-size;
  container-name:find;
  --map-height:28rem;
}

.find-us__inner{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-snug);
}

.find-us__heading{text-align:center}

.find-us__row{
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:flex-start;
  gap:var(--space-snug);
}

.find-us__place{
  flex:1;
  min-inline-size:min(100%, 24rem);
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-snug);
}
.find-us__intro{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
}
.find-us__address{
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
}

.find-us__hours{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
}
.find-us__hours-heading{
  font-family:var(--font-display);
  font-size:var(--type-h4);
  line-height:var(--line-height-normal);
}
.find-us__hours-note{
  max-inline-size:var(--measure-prose);
  font-weight:var(--font-body-medium);
  line-height:var(--line-height-relaxed);
}

.hours-list{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-hair);
  margin:0;
}
.hours-list__row{
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap:var(--space-tight);
}
.hours-list__day{
  inline-size:7ch;           /* ch: the column is sized by the longest day name */
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
}
.hours-list__time{
  margin:0;
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-variant-numeric:tabular-nums;
}

/* The map slot holds either the placeholder or, once asked for, the iframe.
   Both take the same footprint (--map-height, tuned per tier in layout.css)
   so pressing the button swaps the picture without moving the page. */
.find-us__map-slot{inline-size:100%}
.find-us__map{
  inline-size:100%;
  block-size:var(--map-height);
  border:0;
}
/* The stand-in: the site's tint and salt-lines texture, so it reads as a
   quiet part of the page rather than as a broken embed. */
.find-us__map-placeholder{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--space-tight);
  inline-size:100%;
  min-block-size:var(--map-height);
  padding:var(--space-snug) var(--space-tight);
  background:var(--surface-tint) var(--texture-salt-lines) 50% / cover no-repeat;
  text-align:center;
}
.find-us__map-note{
  max-inline-size:var(--measure-short);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.find-us__map-actions{
  display:flex;
  flex-flow:row wrap;
  justify-content:center;
  align-items:center;
  gap:var(--space-tight);
}

@container find (max-width: 44rem){
  .find-us__inner{gap:var(--space-tight)}
  .find-us__place{gap:var(--space-tight)}
}

/* ==========================================================================
   menu-tabs — the three menus.
   --tab-cols and --tab-size are set in layout.css, as is the .is-tabbed
   panel switching.
   ========================================================================== */

.menu-tabs__inner{
  /* The section rule measures against THIS box, which is why it matches the
     length of the same mark on every other page. --rule-offset pulls it up
     from the content rather than clearing a whole section's padding, so the
     gap below it stays short. */
  position:relative;
  --rule-offset:var(--space-snug);
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-snug);
}

.menu-tabs__tablist{
  padding-block-start:var(--space-tight);
  display:grid;
  grid-template-columns:var(--tab-cols);
  align-items:baseline;
}
.menu-tab{
  text-align:center;
  font-family:var(--font-display);
  font-size:var(--tab-size);
  line-height:var(--line-height-tight);
  font-weight:var(--font-display-bold);
  /* The design ghosts inactive tabs in --piren-sage, which lands at ~1.4:1 on
     cream. These are controls, so they hold to the 3:1 large-text floor;
     primary-500 keeps the ghosted read while clearing it at ~3.8:1. */
  color:var(--color-primary-500);
  cursor:pointer;
  transition:color var(--duration-medium) var(--ease-emphasis);
}
.menu-tab:hover,
.menu-tab.is-active{color:var(--text-heading)}

.menu-tabs__panels{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--section-y-sm);
}
.menu-panel__groups{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--section-y-sm);
}
.menu-tabs__groups{
  align-self:center;
  text-align:center;
  line-height:var(--line-height-relaxed);
}

.menu-lunch{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-tight);
}
.menu-lunch__meta{
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:baseline;
  gap:var(--space-hair);
  font-weight:var(--font-body-medium);
}
.menu-lunch__week{display:flex;align-items:baseline;gap:1ch}
/* Holds the price hard right even before script reveals the week number. */
.menu-lunch__price{margin-inline-start:auto}

.menu-lunch__days{display:flex;flex-direction:column;align-items:stretch}

.lunch-block{
  padding:var(--space-hair) 0 var(--space-snug);
  border-block-end:var(--border-width-main) solid var(--border-color-hairline);
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-tight);
}
.lunch-block__name{
  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);
}
.lunch-block__dishes{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-tight);
}

.menu-lunch .dish{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.15rem;
}
.menu-lunch .dish__name{
  font-size:var(--type-md);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
  text-transform:uppercase;
  color:var(--text-heading);
}
.menu-lunch .dish__detail{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}

/* ==========================================================================
   menu-group — a priced list. --row-dir / --row-wrap are set in layout.css.
   ========================================================================== */

.menu-group__head{
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:baseline;
  gap:var(--space-hair);
}
.menu-group__title{
  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);
}
.menu-group__note{font-size:var(--type-xs);color:var(--text-muted)}
.menu-group__note:empty{display:none}

.menu-group__items{display:flex;flex-direction:column;align-items:stretch}

.menu-item{
  padding-block:var(--space-tight);
  border-block-end:var(--border-width-main) solid var(--border-color-hairline);
  display:flex;
  flex-flow:var(--row-dir) var(--row-wrap);
  justify-content:space-between;
  align-items:flex-start;
  gap:var(--space-tight);
}
.menu-item__body{
  flex:1;
  min-inline-size:0;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
}
.menu-item__name{
  font-size:var(--type-body-lg);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
  text-transform:uppercase;
  color:var(--text-heading);
}
.menu-item__meta{
  font-style:italic;
  font-size:var(--type-xs);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.menu-item__from{
  font-style:italic;
  font-weight:var(--font-body-medium);
  font-size:var(--type-xs);
  line-height:var(--line-height-relaxed);
  color:var(--text-heading);
}
.menu-item__detail,
.menu-item__alt{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.menu-item__alt{font-style:italic}

/* Most rows carry only a name and a price. Collapsing the empty paragraphs
   keeps the rhythm even instead of leaving phantom gaps. */
.menu-item__meta:empty,
.menu-item__detail:empty,
.menu-item__alt:empty,
.menu-item__bullets:empty{display:none}

/* The brand mark is a rotated square. Drawing it as a pseudo-element means no
   image request and a bullet that scales with its own text. */
.menu-item__bullets{max-inline-size:var(--measure-prose);color:var(--text-muted)}
.menu-item__bullets ul{display:flex;flex-direction:column;gap:.15rem}
.menu-item__bullets li{
  position:relative;
  padding-inline-start:1rem;
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
}
.menu-item__bullets li::before{
  content:"";
  position:absolute;
  inset-inline-start:0;
  inset-block-start:.55em;
  inline-size:.3em;
  block-size:.3em;
  background:currentColor;
  transform:rotate(45deg);
}

.menu-item__price{
  flex:none;
  padding-block-start:.2rem;
  display:flex;
  align-items:baseline;
  gap:var(--space-tight);
  font-size:var(--type-body);
  line-height:var(--line-height-normal);
}
.menu-item__tier{display:flex;align-items:baseline;gap:.6ch}
.menu-item__amount{font-weight:var(--font-body-medium)}
.menu-item__unit{color:var(--text-muted)}
.menu-item__unit:empty{display:none}

/* ==========================================================================
   benefit-columns — a row of short, titled columns.

   Four shapes from one component: icon-led selling points, a numbered
   sequence, title-and-text alone, and — for a column whose content is a list
   or a set of small records — bullets and rows. The list forms are styled on
   the Julbord page, which is the only page that uses them; see julbord.css.
   ========================================================================== */

.benefit-columns{
  position:relative;
  container-type:inline-size;
  container-name:benefits;
  --benefit-floor:min(100%, 18rem);
}

.benefit-columns__inner{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-snug);
}

.benefit-columns__intro{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-hair);
  text-align:center;
}
.benefit-columns__heading{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h2);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}
.benefit-columns__lead{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
}

/* GRID, NOT FLEX WRAP. As a wrapping flex row with flex:1 the items shared
   each line between them, so a fifth item alone on the second line stretched
   to the full 1393px while its four siblings were 315px. auto-fit sizes the
   tracks once for the whole grid, so a wrapped orphan keeps its column width.

   auto-fit also collapses tracks that no item occupies, so three items still
   spread across the full width as three equal columns — the original
   three-up layout is unchanged. */
.benefit-columns__row{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(var(--benefit-floor), 1fr));
  gap:var(--space-snug);
  align-items:start;
}

.benefit{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-hair);
  text-align:center;
}
.benefit__icon{
  inline-size:var(--size-4-5);
  block-size:var(--size-4-5);
  object-fit:contain;
  display:block;
}
/* The step number. Display face at h2 weight but ghosted, so it orders the
   sequence without competing with the title under it. aria-hidden in the
   markup — the reading order already carries the sequence. */
.benefit__number{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h2);
  line-height:1;
  color:var(--color-primary-500);
}
.benefit__title{
  font-weight:var(--font-body-medium);
  font-size:var(--type-md);
  line-height:var(--line-height-normal);
  color:var(--text-heading);
}
.benefit__text{
  max-inline-size:var(--measure-short);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
/* A numbered step is often a name with nothing to add. */
.benefit__text:empty{display:none}

/* TITLE-AND-TEXT COLUMNS (marker="none") ARE A LIST, NOT A ROW OF BADGES.
   The icon and number forms are short selling points, and centred small text
   under a centred mark is right for them. The Julbord menu is different: five
   columns whose CONTENT is a list, and centred small muted lines made the
   food the hardest thing on the page to read. So this form sets left, at body
   size in body colour.

   The wider floor is what turns five items from a 4+1 orphan into 3+2: at the
   90rem column, 24rem tracks give three, and auto-fit keeps the second row's
   two at the same width as the first row's three. */
.benefit-columns--none .benefit-columns__row{
  grid-template-columns:repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
  gap:var(--space-snug) var(--space-loose);
}
.benefit-columns--none .benefit{
  align-items:flex-start;
  text-align:start;
  padding-block-start:var(--space-hair);
  border-block-start:var(--border-width-main) solid var(--text-heading);
}
.benefit-columns--none .benefit__title{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h4);
  line-height:var(--line-height-tight);
}
.benefit-columns--none .benefit__text{
  max-inline-size:none;
  font-size:var(--type-body);
  color:var(--text-body);
}

.benefit-columns__notes{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.35rem;
  text-align:center;
}
.benefit-columns__note{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.benefit-columns__note--fine{font-style:italic}
.benefit-columns__note:empty{display:none}
.benefit-columns__notes:not(:has(.benefit-columns__note:not(:empty))){display:none}

.benefit-columns__actions{
  display:flex;
  flex-flow:row wrap;
  justify-content:center;
  align-items:center;
  gap:var(--space-tight);
}

/* ==========================================================================
   julbord-hero — the Julbord page's opening statement.
   Brick ground and inverted type tokens are set on the root in layout.css,
   alongside the seasonal band on the home page.
   ========================================================================== */

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

/* Same rule as media-split: the column is the measure, so the eyebrow, the
   h1, the facts and the buttons all share one right edge. */
.julbord-hero__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);
}

.julbord-hero__eyebrow{
  max-inline-size:none;
  font-size:var(--type-xs);
  font-weight:var(--font-body-medium);
  letter-spacing:var(--letter-spacing-eyebrow);
  text-transform:uppercase;
}
.julbord-hero__heading{
  font-size:var(--type-h1);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}
.julbord-hero__lead{
  max-inline-size:none;
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
  font-weight:var(--font-body-medium);
}

/* The facts a guest wants before anything else. Each line takes the brand's
   rotated-square bullet, drawn as a pseudo-element so it costs no request and
   scales with its own text. */
.julbord-hero__facts{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.4rem;
}
.julbord-hero__fact{
  position:relative;
  padding-inline-start:1.4ch;
  font-size:var(--type-body);
  line-height:var(--line-height-relaxed);
}
.julbord-hero__fact::before{
  content:"";
  position:absolute;
  inset-inline-start:0;
  inset-block-start:.62em;
  inline-size:.3em;
  block-size:.3em;
  background:currentColor;
  transform:rotate(45deg);
}

/* A FACT LINE IS THREE ELEMENTS, and the days in the middle are the part a
   guest scans for. The markup carries no whitespace between them, because an
   unused part has to vanish completely rather than leave a space behind, so
   the gap between the parts that ARE set is drawn here instead. .3em is a
   word space in Raleway. */
.julbord-hero__fact-lead:not(:empty),
.julbord-hero__fact-days:not(:empty){margin-inline-end:.3em}
.julbord-hero__fact-lead:empty,
.julbord-hero__fact-days:empty,
.julbord-hero__fact-rest:empty{display:none}
/* A page showing two facts, or one, should not leave the marker behind. This
   replaces a plain :empty test on the line, which stopped matching once the
   line gained three children of its own. */
.julbord-hero__fact:not(:has(.julbord-hero__fact-lead:not(:empty),
                             .julbord-hero__fact-days:not(:empty),
                             .julbord-hero__fact-rest:not(:empty))){display:none}

/* The early-bird callout. A hairline above it and nothing else: the site
   never draws a box around anything, and this used to be the only outlined
   panel on it. The same rule-above treatment as .lunch-week__allweek and the
   buffet-map stops. The text runs at body size — an offer is a selling point,
   not fine print. The exclusions underneath ARE fine print, and are set as
   such: small and muted, so the eye lands on the deadline and the one
   condition that matters, and only then on the list of what it does not
   apply to. */
.julbord-hero__offer{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.35rem;
  max-inline-size:var(--measure-prose);
  padding-block-start:var(--space-tight);
  border-block-start:var(--border-width-main) solid var(--border-color-hairline);
}
.julbord-hero__offer-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);
}
.julbord-hero__offer-text{
  max-inline-size:none;
  font-size:var(--type-body);
  line-height:var(--line-height-relaxed);
}
.julbord-hero__offer-fine{
  max-inline-size:none;
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.julbord-hero__offer-fine:empty{display:none}

.julbord-hero__actions{
  display:flex;
  flex-flow:row wrap;
  align-items:center;
  gap:var(--space-tight);
  margin-block-start:var(--space-hair);
}

/* Capped for the same reason as media-split's frame — see components.css. */
.julbord-hero__media{
  flex:1;
  min-inline-size:min(100%, var(--hero-w));
  max-inline-size:var(--hero-max);
}

@container jbhero (max-width: 44rem){
  .julbord-hero__row{gap:var(--space-tight)}
  /* Two full-width buttons stacked beat two cramped ones side by side. */
  .julbord-hero__actions{align-items:stretch}
  .julbord-hero__actions .btn{flex:1;min-inline-size:min(100%, 14rem)}
}

/* ==========================================================================
   closing-cta — the last thing on the page.
   ========================================================================== */

.closing-cta__inner{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--space-tight);
  text-align:center;
}
.closing-cta__heading{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h2);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}
.closing-cta__lead{
  max-inline-size:var(--measure-prose);
  font-size:var(--type-lead);
  line-height:var(--line-height-normal);
}
.closing-cta__actions{
  display:flex;
  flex-flow:row wrap;
  justify-content:center;
  align-items:center;
  gap:var(--space-tight);
}
.closing-cta__address{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.2rem;
  margin-block-start:var(--space-hair);
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  font-style:normal;
  color:var(--text-muted);
}
.closing-cta__place{font-weight:var(--font-body-medium);color:var(--text-heading)}
.closing-cta__address a{text-decoration:none}
.closing-cta__address a:hover{text-decoration:underline;text-underline-offset:.18em}

/* ==========================================================================
   marquee-strip — two opposing bands of 4:3 photographs.
   ========================================================================== */

.marquee-strip__track{
  display:flex;
  justify-content:flex-start;
  align-items:center;
  gap:var(--grid-gutter);
  will-change:transform;
}

.marquee-tile{
  position:relative;
  inline-size:var(--tile-w);
  flex:none;
  aspect-ratio:4/3;
  overflow:clip;
  background:var(--piren-sage);
}
.marquee-tile__img{
  inline-size:100%;
  block-size:100%;
  object-fit:cover;
  display:block;
}

/* ==========================================================================
   quote-band — one sentence on a slate ground. The band's own background and
   texture live in layout.css.
   ========================================================================== */

.quote-band__inner{
  display:flex;
  flex-direction:column;
  align-items:center;
}
.quote-band__text{
  max-inline-size:var(--measure-prose);
  text-align:center;
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h3);
  line-height:var(--line-height-snug);
}

/* ==========================================================================
   photo-grid — square photographs that lift slightly on hover.
   ========================================================================== */

.photo-grid__grid{
  display:grid;
  grid-template-columns:var(--grid-cols);
  gap:var(--grid-gutter);
}

.photo-tile{
  overflow:clip;
  aspect-ratio:1;
  background:var(--piren-sage);
  --zoom:1;
}
.photo-tile:hover{--zoom:1.08}

.photo-tile__img{
  inline-size:100%;
  block-size:100%;
  object-fit:cover;
  display:block;
  transform:scale(var(--zoom, 1));
  transition:transform var(--duration-fast) var(--ease-exit);
}

/* ==========================================================================
   event-list — two columns of events, split into upcoming and past.
   --evt-cols / --evt-img / --past-opacity are set in layout.css.

   THE GROUP HEADINGS ARE .visually-hidden. Past events are told apart by
   being faded, which needs no label on sight; the headings stay in the markup
   so a screen-reader user, who has no sight of the fading, still learns that
   the second list is the archive.
   ========================================================================== */

.event-list__inner{
  position:relative;
  --rule-offset:var(--space-snug);
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--section-y-sm);
  padding-block-start:var(--space-tight);
}

.event-list__group{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  gap:var(--space-snug);
}

/* THE FADE GOES ON THE GROUP, NOT ON THE CARDS. Each card is a [data-reveal],
   and the reveal animation ends on opacity:1 with fill-mode `both`, so an
   opacity declared on the card itself loses to the animation no matter how
   specific the selector — the dimming simply never appeared. The group is not
   a reveal target, so fading it composites over whatever its children are
   doing. Hovering or tabbing in restores the archive to full strength. */
.event-list__group--past{
  opacity:var(--past-opacity);
  transition:opacity var(--duration-medium) var(--ease-emphasis);
}
.event-list__group--past:hover,
.event-list__group--past:focus-within{opacity:1}

.event-list__items{
  display:grid;
  grid-template-columns:var(--evt-cols);
  gap:var(--space-loose) var(--space-snug);
  align-items:start;
}

/* A data-cms-repeat that matches nothing LEAVES ITS TEMPLATE in the output
   rather than removing it, so an empty group would otherwise render one blank
   card — and the upcoming group is empty for most of the year.

   The template's <time> is the tell: start_datum is required, so every real
   event has a date and only the unbound template has an empty one. Hide that
   row, then hide any group left with no real rows. Without :has() support the
   worst case is one empty card, never a broken page. */
.event-list__items > .event:has(.event__dates time:empty){display:none}
.event-list__group:not(:has(.event:not(:has(.event__dates time:empty)))){display:none}

/* The card is the QUERY CONTAINER; .event__row inside it is the flex box the
   query flips. A @container rule cannot restyle the element that establishes
   the container, so these have to be two elements — see event-list.html.

   align-items:flex-start, NOT stretch. Stretch used to be deliberate: it made
   the picture a full-height band down the side of the card, matching the
   text's height. That band is never square by definition, so squareness and
   stretch cannot both hold — squareness won. */
.event{
  inline-size:100%;
  container-type:inline-size;
  container-name:eventcard;
}
.event__row{
  display:flex;
  flex-flow:row nowrap;
  justify-content:flex-start;
  align-items:flex-start;
  gap:var(--space-tight);
}

/* Beside the words for as long as the words still have room, and only then
   above them. The threshold is the CARD's own width, not the page's: at one
   card per row a phone has plenty of room for a side-by-side, while a card in
   the two-up grid runs out of it much sooner — which is why this cannot be a
   page tier. Below 20rem the text column drops under ~18 characters a line,
   where a description stops reading as a sentence.

   Stacked, the picture takes the full width: an image "above" the text that is
   still 7rem wide reads as a mistake rather than a choice. */
@container eventcard (max-width: 20rem){
  .event__row{flex-direction:column}
  .event__media{inline-size:100%}
}

/* SQUARE IN BOTH LAYOUTS. Two things have to be true for that, and only one
   of them used to be: the row must not stretch the tile (see .event__row), and
   nothing inside it may push it out of shape. An in-flow <img> with
   block-size:100% cannot resolve that percentage — the frame's own height
   comes from aspect-ratio, so it falls back to `auto`, renders at the photo's
   intrinsic ratio, and stretches the frame past the square it was asked for.
   Taking the image out of flow against a definite frame is the other half of
   the fix; same cycle as .nav-card__frame.

   The background is the placeholder: an event with no picture keeps its tile
   and shows the brand glyph on sage rather than collapsing to a text-only row
   that breaks the two-column grid. A real photograph paints over it. */
.event__media{
  position:relative;
  inline-size:var(--evt-img);
  flex:none;
  aspect-ratio:1;
  overflow:clip;
  background:var(--piren-sage) url("/assets/piren/events-glyph.4e73b7dbde54fb36.svg") 50% / 55% no-repeat;
}
.event__img{
  position:absolute;
  inset:0;
  inline-size:100%;
  block-size:100%;
  object-fit:cover;
  display:block;
}

.event__body{
  flex:1;
  min-inline-size:0;
  display:flex;
  flex-flow:row wrap;
  justify-content:space-between;
  align-items:flex-start;
  gap:var(--space-hair) var(--space-tight);
}
.event__text{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.35rem;
}
.event__title{
  font-size:var(--type-xl);
  font-weight:var(--font-body-medium);
  line-height:var(--line-height-normal);
  color:var(--text-heading);
}
.event__dates{
  display:flex;
  flex-flow:row wrap;
  align-items:baseline;
  gap:.7ch;
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.event__until{display:flex;align-items:baseline;gap:.7ch}
.event__lead{
  /* Narrower than running body copy: in half a column, the prose measure
     would set a line wider than the column itself. */
  max-inline-size:var(--measure-short);
  padding-block-start:.5rem;
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
  color:var(--text-muted);
}
.event__lead:empty{display:none}
.event__more{margin-block-start:.6rem}

.event__tickets{
  flex:none;
  display:flex;
  align-items:center;
  gap:.7ch;
  font-size:var(--type-body);
  transition:color var(--duration-medium) var(--ease-default);
}
.event__ticket-mark{
  inline-size:.9rem;
  block-size:.9rem;
  flex:none;
  fill:none;
  stroke:currentColor;
  stroke-width:.09em;
}

/* ==========================================================================
   contact-block — phone and email under a filled section rule.
   --icon-size is set in layout.css.
   ========================================================================== */

.contact-block__inner{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-tight);
}
.contact-block__heading{
  font-family:var(--font-display);
  font-weight:var(--font-display-bold);
  font-size:var(--type-h2);
  line-height:var(--line-height-tight);
  color:var(--text-heading);
}

.contact-block__list{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:var(--space-tight);
}
.contact-item{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.15rem;
}
.contact-item__link{
  display:flex;
  align-items:center;
  gap:var(--space-hair);
}
.contact-item__icon{
  inline-size:var(--icon-size);
  block-size:var(--icon-size);
  flex:none;
  object-fit:contain;
  display:block;
}
.contact-item__value{
  font-size:var(--type-lead);
  font-weight:var(--font-body-medium);
  line-height:var(--line-height-normal);
}
/* Indented to sit under the number rather than under the icon. */
.contact-item__note{
  padding-inline-start:calc(var(--icon-size) + var(--space-hair));
  font-size:var(--type-sm);
  line-height:var(--line-height-relaxed);
}
