/* Cultural School
   White paper. Dark is a choice the visitor makes with the toggle, never
   something the operating system imposes, so the site opens white for
   everyone. One accent, drawn from the wordmark. No tracking anywhere:
   Arabic letterforms join and tracking breaks them. */

:root {
  color-scheme: light;

  --paper: #ffffff;
  --surface: #ffffff;
  --sunk: #f5f5f6;
  --ink: #16161a;
  --muted: #6c6c74;
  --line: rgba(20, 20, 26, 0.11);
  --line-2: rgba(20, 20, 26, 0.055);
  --accent: #6b4a68;
  --accent-ink: #ffffff;
  --shadow: 0 1px 2px rgba(16, 16, 22, 0.05), 0 12px 32px -18px rgba(16, 16, 22, 0.28);

  --pad: clamp(20px, 5vw, 76px);
  --wide: 1280px;
  --r: 14px;
  --r-sm: 10px;
  --control-radius: 10px;
  --pill-radius: 999px;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #252529;
  --surface: #303035;
  --sunk: #202024;
  --ink: #f5f5f3;
  --muted: #b6b6bd;
  --line: rgba(255, 255, 255, 0.13);
  --line-2: rgba(255, 255, 255, 0.07);
  --accent: #c9a9c6;
  --accent-ink: #17131a;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.32), 0 18px 40px -22px rgba(0, 0, 0, 0.58);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
/* any class that sets its own display outranks the browser's own
   [hidden] rule, and the element stays on the page. This puts it back. */
[hidden] { display: none !important; }
button, input, textarea, select { font: inherit; color: inherit; }

/* the sticky bar's real height is measured and written to --barh, so an
   anchor lands just under it instead of behind it. Only one of scroll-padding
   and scroll-margin may be in play: together they double the offset. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--barh, 72px) + 14px);
  /* nothing on the page scrolls sideways except the rails, so a sideways
     swipe should do nothing at all rather than rubber band the document */
  overscroll-behavior-x: none;
  /* This clip lived on body, which quietly cost us the scroller. Giving body
     an overflow other than visible makes body the scrolling box instead of
     the document, and then window.scrollY reads 0 forever, window.scrollTo
     does nothing, and the scroll-behavior and scroll-padding-top above apply
     to an element that no longer scrolls: anchors jump, land behind the bar,
     and switching language loses your place. Clipping here does the same job
     and leaves the document as the thing that scrolls. */
  overflow-x: clip;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: "IBM Plex Sans Arabic", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-weight: 400;
  font-size: clamp(1rem, 0.97rem + 0.15vw, 1.06rem);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
  /* photographs are not dragged out of the page or selected with the text */
  -webkit-user-drag: none;
  user-select: none;
}
a { color: inherit; }

h1, h2, h3 { font-weight: 500; line-height: 1.14; }
h1 { font-size: clamp(2.4rem, 1.4rem + 3.6vw, 4.6rem); font-weight: 500; }
h2 { font-size: clamp(1.9rem, 1.3rem + 2.6vw, 3.4rem); }
h3 { font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem); }

p { color: var(--muted); }
.lede { color: var(--ink); font-size: clamp(1.08rem, 1rem + 0.6vw, 1.42rem); line-height: 1.6; }
.fine { font-size: 0.88rem; color: var(--muted); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.skip-link {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 60;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 20px;
}
.skip-link:focus { inset-inline-start: 0; }

.reveal { opacity: 0; transform: translateY(16px); transition: opacity .7s cubic-bezier(.2,.6,.2,1), transform .7s cubic-bezier(.2,.6,.2,1); }
.reveal.in { opacity: 1; transform: none; }
html:not(.js) .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------------- bar ---------------- */
.bar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: clamp(12px, 3vw, 40px);
  padding: 12px var(--pad);
  /* solid, not frosted: the translucent version tinted the top of the page
     with whatever was scrolling under it */
  background: var(--paper);
  border-bottom: 1px solid var(--line-2);
}

.brand { display: flex; align-items: center; min-height: 44px; }
.brand img { width: clamp(104px, 13vw, 138px); }
:root[data-theme="dark"] .brand img { filter: invert(1) brightness(1.7) contrast(1.1); }

.bar-nav { display: flex; gap: clamp(10px, 2vw, 26px); margin-inline-start: auto; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: none; }
.bar-nav::-webkit-scrollbar { display: none; }

.bar-nav a {
  position: relative;
  text-decoration: none;
  color: var(--muted);
  font-size: 0.95rem;
  white-space: nowrap;
  padding: 6px 2px;
  transition: color .2s;
}
.bar-nav a:hover, .bar-nav a.on { color: var(--ink); }
.bar-nav a.on::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 1.5px;
  background: var(--accent);
}

.bar-tools { display: flex; gap: 8px; flex: none; }

.tool {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--line);
  border-radius: var(--pill-radius);
  background: transparent;
  cursor: pointer;
  font-size: 0.8rem;
  transition: border-color .2s, background .2s;
}
.tool:hover { border-color: var(--accent); }
.tool[href] { color: var(--ink); text-decoration: none; }
.tool-lang { width: auto; padding: 0 14px; border-radius: var(--control-radius); }

/* sun in light, moon in dark, drawn rather than fetched */
.tool-ico { width: 15px; height: 15px; border-radius: 50%; background: currentColor; box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.4px currentColor; }
:root[data-theme="dark"] .tool-ico { box-shadow: inset -4px -1px 0 0 currentColor; background: transparent; border: 1.6px solid currentColor; }

/* four controls plus the wordmark is a lot for a narrow phone, so the pills
   and the mark give up a little size rather than the bar giving up a row */
@media (max-width: 400px) {
  .tool { width: 36px; height: 36px; }
  .tool-lang { padding: 0 10px; }
  .brand img { width: 92px; }
  .bar { gap: 8px; padding-inline: 16px; }
  .bar-tools { gap: 6px; }
}

@media (max-width: 760px) {
  /* The public header becomes two rows on a phone. Keeping both rows pinned
     obscures forms and leaves too little reading space, so it participates in
     the normal page scroll on mobile. The admin has its own navigation rules
     and is deliberately unaffected. */
  html.public-document { scroll-padding-top: 14px; }
  .public-document .bar { position: relative; top: auto; }
  .bar { flex-wrap: wrap; row-gap: 6px; }
  .bar-nav { order: 3; width: 100%; margin-inline-start: 0; }
  .bar-nav a { min-height: 42px; display: flex; align-items: center; }
  .bar-tools { margin-inline-start: auto; }
}

/* ---------------- hero ---------------- */
.hero {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(28px, 4vw, 56px) var(--pad) clamp(28px, 4vw, 56px);
  display: grid;
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
@media (min-width: 900px) {
  /* the facade is wide and short, so the columns are sized to it rather than
     to the viewport, which is what left the dead space */
  .hero { grid-template-columns: minmax(0, 0.78fr) minmax(0, 1.22fr); }
}
.hero-in { max-width: none; }
.hero h1 {
  margin: 0.1em 0 0;
  max-width: 16ch;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: clamp(20px, 2.4vw, 28px); }
@media (max-width: 760px) {
  .hero-actions {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 8px;
  }
  .hero-actions .btn { width: 100%; padding-inline: 12px; }
  .hero-actions .hero-book-action { display: none; }
}

.hero-art { margin: 0; }
.hero-art img { width: 100%; border-radius: var(--r); }
@media (min-width: 900px) {
  /* let it run past the column edge, toward the page margin */
  .hero-art { margin-inline-end: calc(-1 * var(--pad) / 2); }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 48px;
  padding: 0 26px;
  border: 1px solid transparent;
  border-radius: var(--control-radius);
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
  font-size: 0.97rem;
  white-space: nowrap;
  cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.btn:hover { background: color-mix(in srgb, var(--ink) 86%, var(--accent)); }
.btn:active { background: color-mix(in srgb, var(--ink) 78%, var(--accent)); }

.btn.ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn.ghost:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); border-color: var(--ink); color: var(--ink); }
.btn.ghost:active { background: color-mix(in srgb, var(--ink) 10%, transparent); }
.btn.full { width: 100%; }

/* A visit is the lightest request on the site, so its form is immediately
   available and asks only for a name, one contact and a preferred time. */
.request-pane-head { display: grid; gap: 8px; margin-bottom: clamp(20px, 3vw, 30px); max-width: 62ch; }
.request-pane-head p { color: var(--muted); }
.visit-grid { display: grid; gap: clamp(22px, 3vw, 40px); align-items: start; }
@media (min-width: 800px) { .visit-grid { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); } }
.visit-form { display: grid; gap: 16px; }
.visit-form .fields { display: grid; gap: 14px; }
@media (min-width: 560px) { .visit-form .fields { grid-template-columns: 1fr 1fr; } .visit-form .wide { grid-column: 1 / -1; } }
.visit-form .btn { justify-self: start; }
@media (max-width: 519px) { .visit-form .btn { justify-self: stretch; width: 100%; } }
.visit-aside { display: grid; gap: 12px; }
.visit-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.visit-actions .btn { flex: 0 1 auto; }
@media (max-width: 519px) { .visit-actions .btn { flex: 1 1 100%; } }
@media (max-width: 559px) {
  .visit-grid { gap: 20px; }
  .visit-form .fields { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .visit-form .fields > label { grid-column: 1 / -1; min-width: 0; gap: 4px; }
  .visit-form .fields input {
    width: 100%; min-width: 0; max-width: 100%; min-height: 44px; padding: 8px 10px;
    -webkit-appearance: none; appearance: none;
  }
  .visit-aside { gap: 8px; }
}

/* ---------------- bands ---------------- */
.band {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(56px, 8vw, 120px) var(--pad);
}
.band.alt {
  max-width: none;
  background: var(--sunk);
  border-block: 1px solid var(--line-2);
}
.band.alt > * { max-width: var(--wide); margin-inline: auto; }

.band-head { margin-bottom: clamp(20px, 3vw, 34px); }
.tag { font-size: 0.85rem; color: var(--accent); }
.band h2 { letter-spacing: -0.01em; }

/* One direct choice, then one task. Only the selected route occupies space. */
.request-switch {
  width: min(100%, 520px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  margin-bottom: clamp(32px, 5vw, 52px);
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: calc(var(--control-radius) + 4px);
  background: var(--sunk);
}
.request-switch button {
  min-height: 48px;
  padding: 8px 14px;
  border: 1px solid transparent;
  border-radius: var(--control-radius);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.request-switch button:hover { color: var(--ink); }
.request-switch button[aria-selected="true"] {
  color: var(--ink);
  background: var(--paper);
  border-color: var(--line-2);
  box-shadow: var(--shadow);
}
.request-pane[hidden] { display: none !important; }
@media (prefers-reduced-motion: no-preference) {
  .request-pane:not([hidden]) { animation: request-in .24s cubic-bezier(.32, .72, 0, 1); }
}
@keyframes request-in {
  from { opacity: 0; transform: translateY(6px); }
}
@media (max-width: 519px) {
  .request-hub { padding-top: 44px; padding-bottom: 52px; }
  .request-switch { width: 100%; margin-bottom: 32px; }
  .request-switch button { padding-inline: 8px; }
}

.lede-grid { display: grid; gap: clamp(16px, 2.4vw, 30px); max-width: 96ch; }
@media (min-width: 900px) { .lede-grid { grid-template-columns: 1.1fr 1fr; align-items: start; } }

/* figures */
.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: clamp(14px, 2vw, 22px);
  margin: clamp(32px, 5vw, 60px) 0 clamp(40px, 6vw, 72px);
}
.figures > div { border-top: 1px solid var(--line); padding-top: 16px; }
.figures dt { font-size: clamp(1.8rem, 1.2rem + 2.4vw, 3rem); font-weight: 500; line-height: 1; direction: ltr; unicode-bidi: isolate; text-align: start; }
.figures dd { color: var(--muted); font-size: 0.94rem; margin-top: 8px; }

/* previous work rail */
.works-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: clamp(36px, 5vw, 64px); margin-bottom: 18px; }
.rail-nav { display: flex; gap: 8px; }

.works {
  list-style: none;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(232px, 292px);
  gap: clamp(12px, 1.6vw, 20px);
  overflow-x: auto;
  /* the other axis computes to auto once this one is set, which let the rail
     drift vertically by the height of the reveal transform */
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  padding-bottom: 10px;
  scrollbar-width: thin;
}
.work { scroll-snap-align: start; min-width: 0; }
.work img { width: 100%; height: clamp(150px, 18vw, 190px); object-fit: cover; border-radius: var(--r-sm); margin-bottom: 12px; }
.work-when { font-size: 0.82rem; color: var(--accent); }
.work h3 { margin: 2px 0 4px; }
.work-note { font-size: 0.9rem; }

/* two short columns: what the school offers, who it has worked with */
.cols {
  display: grid;
  gap: clamp(24px, 3.4vw, 52px);
  margin-top: clamp(36px, 5vw, 64px);
  padding-top: clamp(28px, 4vw, 44px);
  border-top: 1px solid var(--line-2);
}
@media (min-width: 720px) { .cols { grid-template-columns: repeat(2, 1fr); } }
.col { min-width: 0; }
.col h3 { font-size: 1.02rem; color: var(--accent); margin-bottom: 16px; }
.col .plain { list-style: none; display: grid; gap: 12px; }
.col .plain li { font-size: 0.95rem; line-height: 1.75; padding-inline-start: 16px; position: relative; }
.col .plain li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.72em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}
/* logo walls: every mark sits on its own white tile so the dark wordmarks
   stay readable when the site is in dark mode */
.wall { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 8px; }
.wall li {
  background: #ffffff;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  /* a fixed height, because a ratio plus a full height image is circular
     and the tiles come out ragged */
  height: clamp(62px, 6.5vw, 82px);
  display: grid;
  place-items: center;
  padding: 9px 12px;
  min-width: 0;
  min-height: 0;
}
.wall img { width: 100%; height: 100%; object-fit: contain; mix-blend-mode: multiply; }

.plan {
  /* a drawing, not a hero: capped so it does not take a whole screen */
  max-width: 620px;
  margin-top: clamp(28px, 4vw, 48px);
  margin-inline: auto;
  background: #ffffff;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  padding: clamp(14px, 2.4vw, 28px);
}
.plan img { width: 100%; height: auto; mix-blend-mode: multiply; }
.plan figcaption { margin-bottom: clamp(14px, 2vw, 20px); text-align: center; }
.plan figcaption h3 { font-size: 1.02rem; color: var(--accent); margin-bottom: 6px; }
.plan figcaption p { font-size: 0.9rem; color: var(--muted); max-width: 46ch; margin-inline: auto; }


/* Theme and language cross fade through a view transition, with a touch of
   blur so the change reads as a settle rather than a cut. */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: .34s;
    animation-timing-function: cubic-bezier(.32, .72, 0, 1);
    mix-blend-mode: normal;
  }
  ::view-transition-old(root) { animation-name: cs-fade-out; }
  ::view-transition-new(root) { animation-name: cs-fade-in; }
}
@keyframes cs-fade-out { to { opacity: 0; filter: blur(7px); } }
@keyframes cs-fade-in { from { opacity: 0; filter: blur(7px); } }

/* ---------------- events ---------------- */
/* The tile matches the whatsnext app: the radius, the scrim and the two
   translucent chips are the values given in their integration guide, so a
   listing reads the same here as it does in the app. Everything around the
   tile is the site's own. */


.events { list-style: none; display: grid; gap: clamp(16px, 2vw, 24px); }
@media (min-width: 720px) { .events { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .events { grid-template-columns: repeat(3, 1fr); } }

.event { display: flex; flex-direction: column; gap: 12px; }
/* listings arrive one after another rather than appearing all at once */
@media (prefers-reduced-motion: no-preference) {
  .event { animation: cs-rise .5s cubic-bezier(.32, .72, 0, 1) backwards; }
}
@keyframes cs-rise {
  from { opacity: 0; transform: translateY(12px); }
}

.tile {
  border-radius: 12px;
  overflow: hidden;
  position: relative;
  aspect-ratio: 3 / 2;
  display: block;
  background: var(--surface);
}
.tile-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* a listing with no artwork still needs a dark ground for the white text */
.tile.no-art { background: var(--ink); }

.tile-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.72) 0%, rgba(0,0,0,.15) 45%, rgba(0,0,0,.25) 100%);
}

.tile-top, .tile-bottom {
  position: absolute;
  inset-inline: 14px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  color: #fff;
}
.tile-top { top: 14px; }
.tile-bottom { bottom: 14px; align-items: flex-end; }

.tile-date { font-size: 0.86rem; }
.tile-pill {
  background: rgba(255,255,255,.85);
  color: #17171c;
  border-radius: 20px;
  padding: 4px 12px;
  font-size: 0.78rem;
  white-space: nowrap;
}
.tile-pill.soldout { background: rgba(0,0,0,.62); color: #fff; }

.tile-said { min-width: 0; }
.tile-said h3 { font-size: 1.1rem; color: #fff; }
.tile-city { font-size: 0.85rem; opacity: 0.85; }

.tile-mark {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  background: rgba(255,255,255,.22);
  border-radius: 8px;
  overflow: hidden;
}
.tile-mark img { width: 100%; height: 100%; object-fit: contain; }

.event-sum { font-size: 0.92rem; color: var(--muted); }
.event-foot { margin-top: auto; display: grid; gap: 8px; }
.event-price { font-size: 0.88rem; color: var(--muted); }
.event-foot .btn { min-height: 44px; font-size: 0.94rem; }


.empty { padding: 40px 0; color: var(--muted); }

/* ---------------- booking ---------------- */
.booker { display: grid; gap: clamp(24px, 3.4vw, 44px); align-items: start; margin-top: clamp(28px, 4vw, 44px); }
@media (min-width: 960px) { .booker { grid-template-columns: minmax(0, 1.65fr) minmax(280px, 0.85fr); } }

.booker-main { display: grid; gap: clamp(22px, 3vw, 32px); }

.step { border: 0; border-top: 1px solid var(--line); padding-top: clamp(18px, 2.4vw, 26px); }
.step:first-child { border-top: 0; padding-top: 0; }


.space-picker { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; }
.space-opt {
  text-align: start;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  padding: 14px 16px;
  cursor: pointer;
  display: grid;
  gap: 2px;
  transition: border-color .2s, background .2s;
}
.space-opt:hover { border-color: var(--accent); }
.space-opt.is-on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--surface)); }
.space-opt b { font-weight: 500; }
.space-opt span { font-size: 0.85rem; color: var(--muted); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: clamp(16px, 2vw, 22px); }
.chip {
  min-height: 42px;
  padding: 0 18px;
  border: 1px solid var(--line);
  border-radius: var(--pill-radius);
  background: var(--surface);
  cursor: pointer;
  font-size: 0.94rem;
  transition: border-color .2s, background .2s, color .2s;
}
.chip:hover { border-color: var(--accent); }
.chip.is-on { background: var(--ink); color: var(--paper); border-color: transparent; }

/* the date and time fold away once a slot is chosen, so the form is not
   dominated by a calendar */
.fold { display: block; }
.fold > summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  list-style: none;
  margin-bottom: 16px;
  font-size: 1.02rem;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after {
  content: "";
  width: 8px;
  height: 8px;
  /* physical sides, so the caret points down in both directions rather than
     flipping sideways in Arabic */
  border-right: 1.6px solid var(--muted);
  border-bottom: 1.6px solid var(--muted);
  transform: rotate(45deg);
  transition: transform .18s ease;
  align-self: center;
  flex: none;
  margin-inline-start: auto;
}
.fold[open] > summary::after { transform: rotate(225deg); }
.fold-when { font-size: 0.88rem; color: var(--muted); }
.fold-body { display: grid; gap: 16px; }
.fold[open] .fold-when { display: none; }

.cal { max-width: 340px; border: 1px solid var(--line); border-radius: var(--r); padding: clamp(10px, 1.6vw, 14px); background: var(--surface); }
.cal-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.cal-month { color: var(--ink); font-size: 0.98rem; }
.cal-weekdays, .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; }
.cal-weekdays { margin-bottom: 6px; font-size: 0.72rem; color: var(--muted); text-align: center; }
.cal-day {
  aspect-ratio: 1;
  min-height: 32px;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: var(--control-radius);
  background: var(--sunk);
  cursor: pointer;
  font-size: 0.84rem;
}
.cal-day:hover:not(:disabled) { border-color: var(--accent); }
.cal-day:disabled { background: transparent; color: var(--muted); opacity: 0.35; cursor: default; }
.cal-day.is-on { background: var(--ink); color: var(--paper); }

.fields { display: grid; gap: 14px; }
@media (min-width: 680px) { .fields { grid-template-columns: repeat(2, 1fr); } .wide { grid-column: 1 / -1; } }
.fields label { display: grid; gap: 6px; font-size: 0.9rem; color: var(--muted); }
.fields input, .fields textarea {
  /* 16px stops iOS zooming the page on focus */
  font-size: 16px;
  width: 100%;
  padding: 12px 14px;
  min-height: 48px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.fields textarea { resize: vertical; min-height: 104px; }
.fields input:focus, .fields textarea:focus { border-color: var(--accent); outline: none; }
.mail { overflow-wrap: anywhere; }

.booker-side { display: grid; gap: 14px; position: sticky; top: 96px; }
@media (max-width: 959px) { .booker-side { position: static; } }
.card { border: 1px solid var(--line); border-radius: var(--r); padding: clamp(18px, 2.4vw, 24px); background: var(--surface); display: grid; gap: 12px; box-shadow: var(--shadow); }
.summary { font-size: 0.95rem; color: var(--ink); min-height: 3em; }
.msg { font-size: 0.88rem; min-height: 1.2em; color: var(--muted); }
.msg.is-err { color: #b4342c; }
.msg.is-ok { color: #1f7a4d; }
:root[data-theme="dark"] .msg.is-err { color: #ff8f86; }
:root[data-theme="dark"] .msg.is-ok { color: #6fd39b; }

.mail { display: inline-flex; align-items: center; min-height: 44px; color: var(--ink); font-size: 0.95rem; text-decoration: none; border-bottom: 1px solid var(--accent); direction: ltr; unicode-bidi: isolate; }

/* ---------------- 404 ---------------- */
.notfound {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(60px, 12vh, 140px) var(--pad);
  display: grid;
  gap: 14px;
  justify-items: start;
  align-content: center;
  min-height: 60svh;
}
.notfound h1 { font-size: clamp(2rem, 1.4rem + 2.6vw, 3.4rem); }

/* ---------------- foot ---------------- */
.foot {
  max-width: var(--wide);
  margin-inline: auto;
  padding: clamp(32px, 4vw, 56px) var(--pad);
  border-top: 1px solid var(--line-2);
  display: grid;
  gap: 10px;
  justify-items: center;
  text-align: center;
}
.foot p { font-size: 0.9rem; }
.foot-mark { display: block; line-height: 0; margin: 6px 0; }
.foot-mark img { width: clamp(120px, 16vw, 158px); height: auto; }
:root[data-theme="dark"] .foot-mark img { filter: invert(1) brightness(1.7) contrast(1.1); }

/* One chevron drawn as an svg, pointed by rotation. Angle quotation marks
   are bidi mirrored, so glyphs cannot be relied on inside an RTL page. */
.chev { display: block; transition: transform .15s ease; }

/* the source path points right; previous turns to face back */
[data-rail="prev"] .chev, #calPrev .chev { transform: rotate(180deg); }
[data-rail="next"] .chev, #calNext .chev { transform: none; }

[dir="rtl"] [data-rail="prev"] .chev, [dir="rtl"] #calPrev .chev { transform: none; }
[dir="rtl"] [data-rail="next"] .chev, [dir="rtl"] #calNext .chev { transform: rotate(180deg); }

/* ---------------- form errors ---------------- */
/* An error is said three times over: in a summary the keyboard lands on, on
   the field itself, and in the status line beside the send button. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.form-alert {
  grid-column: 1 / -1;
  border: 1px solid color-mix(in srgb, #b4342c 45%, var(--line));
  border-inline-start: 3px solid #b4342c;
  border-radius: var(--r-sm);
  background: color-mix(in srgb, #b4342c 6%, var(--surface));
  padding: 14px 16px;
  display: grid;
  gap: 8px;
}
:root[data-theme="dark"] .form-alert { border-color: color-mix(in srgb, #ff8f86 40%, var(--line)); border-inline-start-color: #ff8f86; }
.form-alert h3 { font-size: 1rem; color: var(--ink); }
.form-alert ul { list-style: none; display: grid; gap: 4px; }
.form-alert a { font-size: 0.92rem; color: var(--ink); text-underline-offset: 3px; }

.field-err {
  font-size: 0.84rem;
  color: #b4342c;
  min-height: 0;
}
.field-err:empty { display: none; }
:root[data-theme="dark"] .field-err { color: #ff8f86; }
.fields input[aria-invalid="true"], .fields textarea[aria-invalid="true"] { border-color: #b4342c; }
:root[data-theme="dark"] .fields input[aria-invalid="true"] { border-color: #ff8f86; }

/* the summary marker turns red while a step still holds an error, so a
   folded-away problem is not invisible */
.fold.has-err > summary { color: #b4342c; }
:root[data-theme="dark"] .fold.has-err > summary { color: #ff8f86; }

/* ---------------- pending ---------------- */
.btn[aria-busy="true"], .btn:disabled { opacity: 0.6; cursor: default; }
.btn:disabled:hover { background: var(--ink); }
.btn.ghost:disabled:hover { background: transparent; border-color: var(--line); color: var(--ink); }

/* ---------------- loading placeholders ---------------- */
/* Three tiles of the right shape hold the space the listings will take, so
   the page does not jump when they arrive. */
/* the events band is already --sunk, so a placeholder made of --sunk was
   invisible: these are mixed a step away from whatever is behind them */
.event.skel .tile { background: color-mix(in srgb, var(--ink) 7%, var(--surface)); border: 1px solid var(--line-2); }
.event.skel .skel-line { height: 12px; border-radius: 6px; background: color-mix(in srgb, var(--ink) 7%, var(--surface)); }
.event.skel .skel-line.short { width: 45%; }
@media (prefers-reduced-motion: no-preference) {
  .event.skel .tile, .event.skel .skel-line { animation: cs-pulse 1.4s ease-in-out infinite; }
}
@keyframes cs-pulse { 50% { opacity: 0.45; } }

/* ---------------- rail ends ---------------- */
.tool:disabled { opacity: 0.32; cursor: default; }
.tool:disabled:hover { border-color: var(--line); }

/* ---------------- newsletter ---------------- */
.news { display: grid; gap: clamp(20px, 3vw, 40px); align-items: start; }
@media (min-width: 860px) { .news { grid-template-columns: 1.1fr 1fr; } }
.news-said p { margin-top: 12px; max-width: 46ch; }

/* the field and its button sit on one line where there is room, and the two
   messages span the full width underneath so neither pushes the other about */
.news-form { display: grid; gap: 10px; grid-template-columns: 1fr auto; align-items: end; }
@media (max-width: 520px) { .news-form { grid-template-columns: 1fr; } }
.news-field { display: grid; gap: 6px; font-size: 0.9rem; color: var(--muted); min-width: 0; }
.news-field input {
  /* 16px stops iOS zooming the page on focus, as in the booking fields */
  font-size: 16px;
  width: 100%;
  padding: 12px 14px;
  min-height: 48px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.news-field input:focus { border-color: var(--accent); outline: none; }
.news-field input[aria-invalid="true"] { border-color: #b4342c; }
:root[data-theme="dark"] .news-field input[aria-invalid="true"] { border-color: #ff8f86; }
.news-form .field-err, .news-form .msg { grid-column: 1 / -1; }
.news-form .msg:empty { display: none; }

/* a slot somebody already has: shown, so the hour is not simply missing,
   but plainly not on offer */
.chip.is-gone {
  opacity: 0.4;
  cursor: not-allowed;
  text-decoration: line-through;
}
.chip.is-gone:hover { border-color: var(--line); background: transparent; }
