/* ==========================================================================
   Estudi Musical 143 — components
   Every value here comes from tokens.css. No raw hex, no magic numbers.
   Class names are prefixed em- so they survive the move into WordPress
   without colliding with core block classes.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--em-white);
  color: var(--em-ink);
  font-family: var(--em-font-body);
  font-size: var(--em-size-body);
  line-height: var(--em-lh-body);
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; height: auto; display: block; }

a { color: var(--em-red); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--em-red-dark); }

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

/* Keyboard users land here first. */
.em-skip {
  position: absolute; left: -9999px;
  background: var(--em-ink); color: var(--em-white);
  padding: var(--em-s-2) var(--em-s-3); z-index: 100;
}
.em-skip:focus { left: var(--em-s-2); top: var(--em-s-2); }

/* --- Layout --------------------------------------------------------------- */

.em-container {
  max-width: var(--em-container);
  margin-inline: auto;
  padding-inline: var(--em-gutter);
}

.em-section { padding-block: var(--em-s-7); }
.em-section--paper { background: var(--em-paper); }
.em-section--tight { padding-block: var(--em-s-6); }

/* --- Type ----------------------------------------------------------------- */

h1, h2, h3 { margin: 0; font-weight: 400; }

.em-display {
  font-family: var(--em-font-display);
  text-wrap: balance;
  font-size: var(--em-size-display);
  line-height: var(--em-lh-tight);
  letter-spacing: -.015em;
  max-width: 18ch;
}

.em-h2 {
  font-family: var(--em-font-display);
  /* Beige, as the current site sets its section headings. Only ever used
     large: 3.4:1 clears AA for large text but not for body copy. */
  color: var(--em-sand-head);
  text-wrap: balance;
  font-size: var(--em-size-h2);
  line-height: var(--em-lh-snug);
  letter-spacing: -.01em;
  max-width: 22ch;
}

.em-h3 {
  font-family: var(--em-font-body);
  font-size: var(--em-size-h3);
  font-weight: 600;
  line-height: var(--em-lh-snug);
  letter-spacing: -.01em;
}

.em-kicker {
  font-size: var(--em-size-micro);
  font-weight: 600;
  letter-spacing: var(--em-track-kicker);
  text-transform: uppercase;
  color: var(--em-sand-ink);
  margin: 0 0 var(--em-s-3);
}

.em-lead {
  font-size: var(--em-size-lead);
  line-height: 1.55;
  color: var(--em-ink);
  max-width: 46ch;
}

.em-prose { max-width: var(--em-measure); }
.em-prose p { margin-block: 0 var(--em-s-2); }
.em-muted { color: var(--em-ink-60); }

/* --- Buttons -------------------------------------------------------------- */

.em-btn {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  padding: .85em 1.6em;
  border: 1px solid var(--em-red);
  border-radius: var(--em-radius-pill);
  background: var(--em-red);
  color: var(--em-white);
  font-size: var(--em-size-body);
  font-weight: 500;
  line-height: 1;
  text-decoration: none;
  transition: background var(--em-transition), border-color var(--em-transition);
}
.em-btn:hover { background: var(--em-red-dark); border-color: var(--em-red-dark); color: var(--em-white); }

.em-btn--ghost {
  background: transparent;
  color: var(--em-sand-ink);
  border-color: var(--em-sand);
}
.em-btn--ghost:hover {
  background: var(--em-sand-12);
  color: var(--em-sand-ink);
  border-color: var(--em-sand-ink);
}

.em-btns { display: flex; flex-wrap: wrap; gap: var(--em-s-2); }

/* A text link with a moving arrow — used on cards. */
.em-more {
  display: inline-flex; align-items: center; gap: .4em;
  font-size: var(--em-size-small); font-weight: 500;
  text-decoration: none;
}
.em-more::after { content: "→"; transition: transform var(--em-transition); }
/* A short list of them, stacked, as on the Cant page's pair of choirs. */
.em-mores { display: flex; flex-direction: column; align-items: flex-start; gap: var(--em-s-2); }
.em-more:hover::after { transform: translateX(3px); }

/* --- The manuscript grid, revealed --------------------------------------
   The page is plain white at rest. The ruling and its coloured cells live in
   a layer masked down to a soft circle following the cursor, so the grid
   appears only where you are looking and fades again when you leave.

   Two layers sit at z-index 0 — the revealed one and the hero's permanent
   cluster — and every section's content sits at z-index 1 above them.
   -------------------------------------------------------------------------- */

.em-section, .em-hero { position: relative; }
.em-section > .em-container,
.em-hero    > .em-container { position: relative; z-index: 1; }

.em-reveal {
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  transition: opacity 280ms ease;
  /* --mx/--my are written by the pointer handler at the foot of the page.
     Off-canvas by default so nothing shows before the first movement. */
  -webkit-mask-image: radial-gradient(circle 240px at var(--mx, -999px) var(--my, -999px),
                        #000 0%, #000 32%, transparent 72%);
          mask-image: radial-gradient(circle 240px at var(--mx, -999px) var(--my, -999px),
                        #000 0%, #000 32%, transparent 72%);
}
[data-scatter]:hover > .em-reveal { opacity: 1; }

.em-reveal__grid {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right,  var(--em-rule) 1px, transparent 1px),
    linear-gradient(to bottom, var(--em-rule) 1px, transparent 1px);
  background-size: var(--em-cell) var(--em-cell);
  /* Set in JS so the ruling runs continuously from section to section. */
  background-position: 0 var(--ruled-offset, 0px);
}

/* The hero's permanent cluster: three cells on the diagonal, always visible,
   the one place on the page that carries the brand red at full strength. */
.em-cells {
  position: absolute; inset: 0;
  z-index: 0;
  pointer-events: none; overflow: hidden;
}

.em-cell {
  position: absolute;
  width: var(--em-cell); height: var(--em-cell);
  background: var(--em-red-25);
}
.em-cell--strong { background: var(--em-red); }
.em-cell--warm   { background: var(--em-red-70); }
.em-cell--mid    { background: var(--em-red-45); }
.em-cell--faint  { background: var(--em-red-12); }
.em-cell--sand   { background: var(--em-sand-12); }

/* --- Header --------------------------------------------------------------- */

.em-header {
  border-bottom: 1px solid var(--em-rule);
  background: var(--em-white);
  position: relative;
  z-index: 10;
}

.em-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--em-s-4);
  min-height: 132px;
}

/* The mark is the artwork; the name beside it is live text in the display
   serif — the same face as "l'Estudi Musical 143" in the hero — so it stays
   sharp at any size. The only horizontal lockup file is 335px wide and cannot
   be shown this large without going soft. */
.em-logo {
  display: inline-flex;
  align-items: center;
  gap: .85rem;
  text-decoration: none;
  /* Pulled out of the container's margin so it sits near the window edge, as
     it does on the current site. Resolves to 0 below the container width. */
  margin-left: calc(-1 * max(0px, (100vw - var(--em-container)) / 2));
}
.em-logo__mark { display: block; }
.em-logo__mark img { height: 108px; width: auto; display: block; }

.em-logo__name {
  font-family: var(--em-font-display);
  /* Three lines at this size stand as tall as the mark beside them: two full
     line boxes plus one cap height ≈ 2.7em, against the mark's 108px. */
  font-size: 2.5rem;
  line-height: 1;
  letter-spacing: -.01em;
  color: var(--em-red);
}


.em-nav ul { display: flex; gap: var(--em-s-4); list-style: none; margin: 0; padding: 0; }
.em-nav a {
  color: var(--em-ink);
  text-decoration: none;
  font-size: var(--em-size-small);
  font-weight: 500;
  padding-block: var(--em-s-3);
  display: inline-flex; align-items: center; gap: .35em;
}
.em-nav a:hover { color: var(--em-red); }

.em-nav li { position: relative; }
.em-nav__caret { font-size: .6em; color: var(--em-sand-ink); }

/* Submenus open on hover and on keyboard focus — hover alone is not enough. */
.em-nav ul ul {
  position: absolute; top: 100%; left: calc(var(--em-s-2) * -1);
  display: block;
  min-width: 230px;
  flex-direction: column; gap: 0;
  padding: var(--em-s-2) 0;
  background: var(--em-white);
  border: 1px solid var(--em-rule);
  box-shadow: 0 12px 32px rgba(56,56,56,.09);
  opacity: 0; visibility: hidden;
  transition: opacity var(--em-transition);
}
.em-nav li:hover > ul,
.em-nav li:focus-within > ul { opacity: 1; visibility: visible; }
.em-nav ul ul a { padding: .55em var(--em-s-2); width: 100%; }

.em-nav__lang { color: var(--em-sand-ink) !important; }

/* --- Hero ----------------------------------------------------------------
   Welcome on the left, the copy on the right. No illustration.
   -------------------------------------------------------------------------- */

.em-hero { padding-block: clamp(3.5rem, 2rem + 6vw, 6.5rem); }

.em-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-areas:
    "welcome copy"
    "anniv   copy";
  column-gap: var(--em-s-6);
  row-gap: 0;
  align-items: start;
}

.em-hero__welcome { grid-area: welcome; position: relative; z-index: 1; }
.em-anniv         { grid-area: anniv; }
.em-hero__copy    { grid-area: copy; }

/* The welcome is deliberately NOT the h1 — the h1 has to carry the keywords
   Google reads. Two faces: the bold is the body sans, because Instrument
   Serif ships a single weight; the school's name is the display serif, which
   is also narrower and so fits a long line without shrinking it. */
.em-hero__welcome {
  /* Sizing the welcome from its own column rather than from the viewport is
     what lets it fill the space: each line is set in cqw, tuned to span the
     full column width whatever that width turns out to be.

     Two lines, so the block is wider than it is tall: filling the full height
     of the headline beside it would need a third line or a crop. */
  container-type: inline-size;
}

.em-welcome {
  margin: 0;
  display: grid;
  gap: .02em;
  text-align: left;

  /* Both lines span the column, which is also the width of the headline in
     the column beside it, so the two blocks share one measure. Neither line
     may wrap — one pixel of overflow drops "143" onto a line of its own — so
     both are nowrap and sized a hair inside the exact fit, leaving room for
     sub-pixel rounding rather than a scrollbar. */
  white-space: nowrap;
  font-size: 17.40cqw;

  /* Drop the block so its capitals sit on the same line as "Escola de", not
     the kicker above it. That distance is the kicker's own line box plus its
     margin, written in the kicker's tokens so it follows if either changes.
     The 2px is the difference in ascender space between the two faces, which
     varies by under 2px across every width where the columns sit side by
     side — a constant is honest here. */
  margin-top: calc(var(--em-size-micro) * var(--em-lh-body) + var(--em-s-3) + 2px);
}

.em-welcome__a {
  font-family: var(--em-font-body);
  font-weight: 700;
  font-size: clamp(2rem, .85rem + 4.1vw, 3.9rem);   /* fallback */
  font-size: 1em;
  line-height: .98;
  letter-spacing: -.045em;
  color: var(--em-red-45);
}

.em-welcome__b {
  font-family: var(--em-font-display);
  font-size: clamp(1.85rem, .75rem + 3.9vw, 3.6rem); /* fallback */
  font-size: 16.13cqw;
  line-height: 1;
  letter-spacing: -.015em;
  color: var(--em-red);
}

/* Nothing bleeds out of the hero any more, so it no longer clips, and the
   kicker goes back to the sand — the ink override only existed to clear the
   sketch behind it. With no hero image the LCP element is text again, which
   is the fastest thing it can be. */

.em-hero__lead { margin: var(--em-s-3) 0 var(--em-s-5); }

/* --- Route cards ---------------------------------------------------------- */

.em-routes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--em-rule);
  border-left: 1px solid var(--em-rule);
}

.em-route {
  display: flex;
  flex-direction: column;
  gap: var(--em-s-2);
  padding: var(--em-s-4) var(--em-s-3) var(--em-s-4);
  border-right: 1px solid var(--em-rule);
  border-bottom: 1px solid var(--em-rule);
  text-decoration: none;
  color: inherit;
  background: var(--em-white);
  transition: background var(--em-transition);
}
/* Hover picks up the grid's own pale tiles. The pattern repeats every four
   cards rather than every other one: on a two-column grid that reads as a
   checkerboard instead of colouring the whole left-hand column pink. */
.em-route:hover { background: var(--em-sand-12); color: inherit; }
.em-route:nth-child(4n+1):hover,
.em-route:nth-child(4n+4):hover { background: var(--em-red-12); }
.em-route:hover .em-route__title { color: var(--em-red); }

.em-route__art { display: block; color: var(--em-sand); height: 84px; }
.em-route__art svg { height: 100%; width: auto; }
.em-route:hover .em-route__art { color: var(--em-red-70); }

.em-route__title { transition: color var(--em-transition); }
.em-route p { margin: 0; font-size: var(--em-size-small); color: var(--em-ink-60); }
.em-route .em-more { margin-top: auto; padding-top: var(--em-s-2); }

/* --- Actualitat ----------------------------------------------------------- */

.em-news__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--em-s-3); flex-wrap: wrap;
}

.em-news__grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--em-s-4);
  margin-top: var(--em-s-4);
}

.em-post { display: flex; flex-direction: column; gap: var(--em-s-1); text-decoration: none; color: inherit; }
.em-post__media {
  display: block;
  aspect-ratio: 3 / 2;
  background: var(--em-sand-12);
  overflow: hidden;
  margin-bottom: var(--em-s-1);
}
.em-post__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 400ms ease; }
/* Several Actualitat posts are posters, not photographs: their words are the
   picture, and cropping them to the card's 4:3 cuts the title off. Anything
   whose shape is far from the frame's is fitted inside it instead, on the
   palette's pale sand. build.py sets this from the real pixel size. */
.em-post__media--fit { background: var(--em-sand-12); }
.em-post__media--fit img { object-fit: contain; }
.em-post:hover .em-post__media--fit img { transform: none; }
.em-post:hover .em-post__media img { transform: scale(1.03); }
.em-post time { font-size: var(--em-size-micro); letter-spacing: .06em; text-transform: uppercase; color: var(--em-sand-ink); }
/* Post titles read as normal text, not as headings — they sit in a grid of
   three and the weight was competing with the section heading above. */
.em-post h3 {
  font-weight: 400;
  font-size: var(--em-size-body);
  line-height: var(--em-lh-snug);
  letter-spacing: 0;
  transition: color var(--em-transition);
}
.em-post:hover h3 { color: var(--em-red); }

/* --- On som --------------------------------------------------------------- */

.em-where__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--em-s-6); align-items: start; }
.em-where dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--em-s-1) var(--em-s-3); margin: var(--em-s-4) 0 0; }
.em-where dt { font-size: var(--em-size-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--em-sand-ink); padding-top: .25em; }
.em-where dd { margin: 0; font-size: var(--em-size-small); }
.em-map {
  aspect-ratio: 4 / 3; width: 100%; border: 1px solid var(--em-rule);
  background: var(--em-paper);
  display: grid; place-items: center;
  color: var(--em-ink-60); font-size: var(--em-size-small);
}

/* --- Closing CTA ---------------------------------------------------------- */

.em-cta { background: var(--em-red); color: var(--em-white); text-align: center; }
.em-cta .em-h2 { max-width: 20ch; margin-inline: auto; color: inherit; }
/* Wide enough to hold the sentence on one line; it still wraps on a phone. */
.em-cta p { color: rgba(255,255,255,.86); max-width: 62ch; margin: var(--em-s-2) auto var(--em-s-4); }
.em-cta .em-btn { background: var(--em-white); border-color: var(--em-white); color: var(--em-red); }
/* Warm cream rather than black — black is the one colour on this page that
   belongs to nothing. 8.9:1 for the label. */
.em-cta .em-btn:hover {
  background: var(--em-sand-12);
  border-color: var(--em-sand-12);
  color: var(--em-red-dark);
}
.em-cta .em-btns { justify-content: center; }
.em-cta .em-kicker { color: rgba(255,255,255,.72); }

/* --- Footer --------------------------------------------------------------- */

.em-footer { border-top: 1px solid var(--em-rule); padding-block: var(--em-s-6) var(--em-s-4); font-size: var(--em-size-small); }
.em-footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--em-s-4); }
.em-footer h2 { font-size: var(--em-size-micro); letter-spacing: .1em; text-transform: uppercase; color: var(--em-sand-ink); font-weight: 600; margin-bottom: var(--em-s-2); font-family: var(--em-font-body); }
.em-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .45em; }
.em-footer a { color: var(--em-ink); text-decoration: none; }
.em-footer a:hover { color: var(--em-red); }
/* The same lockup as the header, half the size. */
.em-footer__logo .em-logo { margin: 0 0 var(--em-s-2); gap: .55rem; }
.em-footer__logo .em-logo__mark img { height: 56px; }
.em-footer__logo .em-logo__name { font-size: 1rem; }
.em-footer__legal {
  margin-top: var(--em-s-5); padding-top: var(--em-s-3);
  border-top: 1px solid var(--em-rule);
  display: flex; justify-content: space-between; gap: var(--em-s-3); flex-wrap: wrap;
  color: var(--em-ink-60); font-size: var(--em-size-micro);
}

/* --- Mobile menu button ---------------------------------------------------
   Hidden on desktop; the media query above reveals it.
   -------------------------------------------------------------------------- */
.em-menu-btn {
  display: none;
  align-items: center; gap: .5em;
  background: none; border: 1px solid var(--em-rule);
  border-radius: var(--em-radius-pill);
  padding: .6em 1em;
  font: inherit; font-size: var(--em-size-small); font-weight: 500;
  color: var(--em-ink); cursor: pointer;
}
.em-menu-btn__bars { display: grid; gap: 3px; }
.em-menu-btn__bars span { display: block; width: 16px; height: 1.5px; background: currentColor; }

/* --- Responsive ----------------------------------------------------------
   Only four breakpoints, all of them layout. Type is already fluid.
   -------------------------------------------------------------------------- */

@media (max-width: 1000px) {
  .em-routes    { grid-template-columns: repeat(2, 1fr); }
  .em-news__grid { grid-template-columns: repeat(3, 1fr); gap: var(--em-s-3); }
  .em-footer__grid { grid-template-columns: 1fr 1fr; gap: var(--em-s-5); }
}

@media (max-width: 860px) {
  .em-hero__grid  {
    grid-template-columns: 1fr;
    grid-template-areas: none;
    gap: var(--em-s-5);
  }
  .em-hero__welcome,
  .em-hero__copy,
  .em-anniv { grid-area: auto; }
  /* The offset exists to line the welcome up with the headline beside it.
     Stacked, there is nothing beside it, so it only wastes 46px. */
  .em-welcome     { margin-top: 0; }

  .em-display     { max-width: 15ch; }
  .em-where__grid { grid-template-columns: 1fr; gap: var(--em-s-4); }
  .em-news__grid  { grid-template-columns: 1fr; gap: var(--em-s-4); }
  .em-menu-btn    { display: inline-flex; }
  .em-nav {
    display: none;
    position: absolute; top: 100%; left: 0; right: 0;
    background: var(--em-white);
    border-bottom: 1px solid var(--em-rule);
    box-shadow: 0 16px 32px rgba(56,56,56,.08);
    padding: var(--em-s-2) var(--em-gutter) var(--em-s-4);
    max-height: calc(100vh - 88px); overflow-y: auto;
  }
  .em-nav[data-open="true"] { display: block; }
  .em-nav > ul { flex-direction: column; gap: 0; }
  .em-nav > ul > li { border-bottom: 1px solid var(--em-rule); }
  .em-nav > ul > li:last-child { border-bottom: 0; }
  .em-nav a { padding-block: var(--em-s-2); font-size: var(--em-size-body); }
  /* Submenus are always open on mobile — hover does not exist here. */
  .em-nav ul ul {
    position: static; opacity: 1; visibility: visible;
    border: 0; box-shadow: none; padding: 0 0 var(--em-s-2) var(--em-s-2);
    min-width: 0;
  }
  .em-nav ul ul a { padding-block: .4em; color: var(--em-ink-60); font-size: var(--em-size-small); }
  .em-nav__caret { display: none; }
}

@media (max-width: 560px) {
  /* The logo and the menu button have to share a narrow bar. */
  .em-logo__mark img { height: 68px; }
  .em-logo__name { font-size: 1.55rem; }
  .em-logo { gap: .6rem; }
  .em-routes { grid-template-columns: 1fr; }
  .em-footer__grid { grid-template-columns: 1fr; }
  .em-btns .em-btn { width: 100%; justify-content: center; }
}


/* --- Fifteenth-anniversary lockup ----------------------------------------
   Three layers over one another: the clef, then the logo, then the year.
   The clef is revealed by animating a mask that is stroked along the
   brushstroke's own spiral, so it appears to be painted from the eye of the
   curl outwards rather than simply fading in.

   The three placements are not eyeballed — they were derived by matching the
   red ink of each layer against its position in the original composite.
   -------------------------------------------------------------------------- */

.em-anniv {
  position: relative;
  z-index: 0;                       /* the welcome keeps its crisp edges on top */
  width: min(100%, 440px);
  /* Centred in its column and pulled up over the welcome. Both numbers were
     measured rather than chosen: at this width "quinzè aniversari" ends level
     with the bottom of the buttons in the right-hand column, and the EM mark
     still clears the welcome's last line by ~26px. The clef's tail then runs
     on below the buttons, which is the point — it is the only thing down
     there. */
  margin: -3.5rem auto 0;
}

/* Stacked on a phone, the lockup keeps the place it holds at full width:
   directly under the welcome, overlapping it. Two things have to be paid for
   here. The grid's 3rem row gap now sits between them, so it is cancelled
   first; and the overlap is then set to ~48px on the 388px lockup, the same
   eighth of its own width it overlaps by at 440px.

   This must come after the rule above, not in the stacking block earlier in
   the file: same specificity, and the later rule wins.

   The cost was weighed. The headline and both buttons now begin below the
   fold on a phone — the lockup is the fifteenth-anniversary mark and belongs
   with the welcome that names the school. */
@media (max-width: 860px) {
  .em-anniv { margin: calc(var(--em-s-5) * -1 - 3rem) auto 0; }
}

.em-anniv__clef { display: block; width: 100%; height: auto; }

.em-anniv__logo,
.em-anniv__text { position: absolute; height: auto; }
.em-anniv__logo { left: 16.54%; top: 20.89%; width: 64.47%; }
.em-anniv__text { left:  9.04%; top: 63.18%; width: 68.79%; }

/* Resting state: nothing drawn. */
.em-anniv__trace { stroke-dasharray: 100; stroke-dashoffset: 100; }
.em-anniv__dot   { opacity: 0; transform-box: fill-box; transform-origin: center; }
.em-anniv__logo,
.em-anniv__text  { opacity: 0; }

.em-anniv[data-play="true"] .em-anniv__trace {
  animation: em-anniv-draw 2.4s cubic-bezier(.34,.02,.28,1) forwards;
}
.em-anniv[data-play="true"] .em-anniv__dot--a { animation: em-anniv-pop .5s ease-out 2.10s forwards; }
.em-anniv[data-play="true"] .em-anniv__dot--b { animation: em-anniv-pop .5s ease-out 2.28s forwards; }
.em-anniv[data-play="true"] .em-anniv__logo   { animation: em-anniv-rise .85s cubic-bezier(.2,.7,.3,1) 2.55s forwards; }
.em-anniv[data-play="true"] .em-anniv__text   { animation: em-anniv-rise .85s cubic-bezier(.2,.7,.3,1) 3.15s forwards; }

@keyframes em-anniv-draw { to { stroke-dashoffset: 0; } }
@keyframes em-anniv-pop  { from { opacity: 0; transform: scale(.35); } to { opacity: 1; transform: none; } }
@keyframes em-anniv-rise { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }

/* Anyone who has asked for less movement gets the finished lockup, at once. */
@media (prefers-reduced-motion: reduce) {
  .em-anniv__trace { stroke-dashoffset: 0; }
  .em-anniv__dot,
  .em-anniv__logo,
  .em-anniv__text { opacity: 1; }
  .em-anniv *     { animation: none !important; }
}

/* Visible to screen readers only. */
.em-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- Reveal on scroll -----------------------------------------------------
   Elements fade in from the left as they enter the viewport, and go back when
   they leave, so the movement replays scrolling up as well as down. The
   anniversary lockup is deliberately not in this set — it has its own.

   The transform does not change layout but it does change
   getBoundingClientRect, which the scattered-cell script relies on. That
   script wraps its measuring pass in .em-measuring so it reads the settled
   boxes rather than the pre-animation ones.
   -------------------------------------------------------------------------- */

/* Scoped to .em-js, which the script adds to the root. Without JavaScript the
   page is simply visible — content must never depend on a script to appear. */
.em-js [data-reveal] {
  opacity: 0;
  transform: translateX(-26px);
  transition:
    opacity   .7s cubic-bezier(.2, .7, .3, 1) var(--reveal-delay, 0ms),
    transform .7s cubic-bezier(.2, .7, .3, 1) var(--reveal-delay, 0ms);
}
.em-js [data-reveal].is-in { opacity: 1; transform: none; }

.em-measuring [data-reveal] { transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .em-js [data-reveal] { opacity: 1; transform: none; transition: none; }
}


/* ==========================================================================
   PART TWO — the interior pages
   --------------------------------------------------------------------------
   Everything above this line is the homepage. Everything below is what the
   other twenty-nine pages needed. Each block here becomes one WordPress block
   pattern; the comment above it is the pattern's description.
   ========================================================================== */


/* --- The flor ------------------------------------------------------------
   The Flor de Barcelona, traced from the artwork the school supplied
   (icons/flor.svg). It appears in exactly one place: the grid revealed under
   the cursor, where roughly one accent cell in five is the flower instead of a
   square. It is carried as a mask, so it takes whichever tone of red the cell
   was given.
   -------------------------------------------------------------------------- */

.em-cell--flor {
  -webkit-mask-image: url("icons/flor.svg"); mask-image: url("icons/flor.svg");
  -webkit-mask-size: 88%;                    mask-size: 88%;
  -webkit-mask-position: center;             mask-position: center;
  -webkit-mask-repeat: no-repeat;            mask-repeat: no-repeat;
}


/* --- Rules and list markers ----------------------------------------------
   A hairline between blocks inside a section, and a small square marker on
   lists — the same square the accent cells use, so lists sit in the page's
   own vocabulary rather than borrowing a bullet from nowhere.
   -------------------------------------------------------------------------- */

.em-divider { height: 1px; background: var(--em-rule); margin-block: var(--em-s-6); }

.em-list { list-style: none; margin: var(--em-s-2) 0 0; padding: 0; display: grid; gap: .6em; }
.em-list li { position: relative; padding-left: 1.5em; }
.em-list li::before {
  content: "";
  position: absolute; left: 0; top: .62em;
  width: 7px; height: 7px;
  background: var(--em-sand);
}


/* --- Breadcrumbs ----------------------------------------------------------
   Above the H1 on every interior page, which is also what BreadcrumbList
   schema needs to point at.
   -------------------------------------------------------------------------- */

.em-crumbs { padding-top: var(--em-s-4); }
.em-crumbs ol {
  display: flex; flex-wrap: wrap; gap: .5em;
  list-style: none; margin: 0; padding: 0;
  max-width: var(--em-container);
  margin-inline: auto;
  padding-inline: var(--em-gutter);
  font-size: var(--em-size-micro);
  letter-spacing: .04em;
  color: var(--em-ink-60);
}
.em-crumbs li + li::before { content: "/"; margin-right: .5em; color: var(--em-rule); }
.em-crumbs a { color: var(--em-ink-60); text-decoration: none; }
.em-crumbs a:hover { color: var(--em-red); }
.em-crumbs [aria-current] { color: var(--em-ink); }


/* --- Interior page header -------------------------------------------------
   Kicker, H1, one lead paragraph, and optionally a sketch alongside. Every
   page gets exactly one H1 through this block — the live site has pages with
   none at all.
   -------------------------------------------------------------------------- */

.em-page { padding-block: var(--em-s-5) var(--em-s-6); }
.em-page__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: var(--em-s-6);
  align-items: center;
}
.em-page__grid--wide { grid-template-columns: minmax(0, 1fr); }
.em-page .em-display { max-width: 18ch; }
.em-page__grid .em-sketch img { max-height: 340px; width: auto; margin-inline: auto; }
.em-page__grid .em-sketch--pair { justify-items: center; }
.em-page .em-lead { margin-top: var(--em-s-3); max-width: 54ch; }
.em-page .em-btns { margin-top: var(--em-s-4); }

/* The pencil sketches. They are drawings on paper, so they get no frame, no
   border and no background — anything else makes them look like clip art. */
.em-sketch { margin: 0; }
.em-sketch img { width: 100%; height: auto; display: block; }
.em-sketch--sm { max-width: 320px; }
.em-sketch figcaption {
  margin-top: var(--em-s-1);
  font-size: var(--em-size-micro);
  color: var(--em-ink-60);
}
.em-sketch--pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--em-s-3); align-items: end; }


/* --- Prose ----------------------------------------------------------------- */

.em-prose h2 { margin-top: var(--em-s-5); margin-bottom: var(--em-s-3); }
.em-prose h3 {
  font-family: var(--em-font-body);
  font-size: var(--em-size-h4);
  font-weight: 600;
  margin-top: var(--em-s-4);
  margin-bottom: var(--em-s-1);
}
.em-prose--wide { max-width: 74ch; }

/* A prose page with no sidebar: the instrument pages, once the fee table came
   off them. Same left edge as the split layout, so the two read as one family. */
.em-prose-col { max-width: var(--em-measure); }


/* --- Two columns ----------------------------------------------------------
   Text against a sketch, a table or a fact list.
   -------------------------------------------------------------------------- */

.em-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--em-s-6);
  align-items: start;
}
.em-split--narrow-right { grid-template-columns: minmax(0, 1.35fr) minmax(0, .65fr); }


/* --- Facts ----------------------------------------------------------------
   Who it is for, what age, how long, who teaches it. The live site keeps this
   on a different page from the description; here it sits beside it.
   -------------------------------------------------------------------------- */

.em-facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--em-s-2) var(--em-s-3);
  margin: 0;
  padding: var(--em-s-4);
  background: var(--em-sand-12);
  border-radius: var(--em-radius);
}
.em-facts dt {
  font-size: var(--em-size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--em-sand-ink);
  padding-top: .2em;
}
.em-facts dd { margin: 0; font-size: var(--em-size-small); }
.em-facts a { color: var(--em-red-dark); }


/* --- Tables ---------------------------------------------------------------
   Fees and the school calendar. Scrolls inside itself on a phone rather than
   pushing the page sideways.
   -------------------------------------------------------------------------- */

.em-table-wrap { overflow-x: auto; margin-top: var(--em-s-3); }
.em-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--em-size-small);
}
/* Only for tables that genuinely need the room — the fee list and the school
   calendar. In a narrow column a minimum width silently crops the last column
   instead of scrolling, which is worse than wrapping the headers. */
.em-table--wide { min-width: 34rem; }
.em-table caption {
  text-align: left;
  font-family: var(--em-font-display);
  font-size: var(--em-size-h3);
  color: var(--em-sand-head);
  padding-bottom: var(--em-s-2);
}
.em-table th, .em-table td {
  text-align: left;
  padding: .7em var(--em-s-2) .7em 0;
  border-bottom: 1px solid var(--em-rule);
  vertical-align: top;
}
.em-table thead th {
  font-size: var(--em-size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--em-sand-ink);
  font-weight: 600;
  border-bottom-color: var(--em-ink);
}
.em-table tbody th { font-weight: 400; }
.em-table td:last-child, .em-table th:last-child { padding-right: 0; }
.em-table .em-num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.em-table tr:hover td, .em-table tr:hover th { background: var(--em-sand-12); }
.em-table__group th {
  padding-top: var(--em-s-4);
  font-family: var(--em-font-body);
  font-weight: 600;
  color: var(--em-ink);
  border-bottom-color: var(--em-ink);
}


/* --- Callout --------------------------------------------------------------- */

.em-callout {
  border-left: 3px solid var(--em-red);
  padding: var(--em-s-1) 0 var(--em-s-1) var(--em-s-3);
  margin-block: var(--em-s-4);
}
.em-callout p { margin: 0; }
.em-callout p + p { margin-top: var(--em-s-1); }
.em-callout--sand { border-left-color: var(--em-sand); }


/* --- Steps ----------------------------------------------------------------
   Matrícula: the enrolment flow that replaces a printable PDF.
   -------------------------------------------------------------------------- */

.em-steps { counter-reset: step; display: grid; gap: var(--em-s-4); margin-top: var(--em-s-4); list-style: none; padding: 0; }
.em-steps li { display: grid; grid-template-columns: 2.4rem minmax(0, 1fr); gap: var(--em-s-3); align-items: start; }
.em-steps li::before {
  counter-increment: step;
  content: counter(step);
  font-family: var(--em-font-display);
  font-size: 1.6rem;
  line-height: 1;
  color: var(--em-red);
  border-top: 2px solid var(--em-red);
  padding-top: .35rem;
}
.em-steps h3 { margin: 0 0 .25em; font-size: var(--em-size-h3); }
.em-steps p  { margin: 0; color: var(--em-ink-60); font-size: var(--em-size-small); }


/* --- Professorat ----------------------------------------------------------
   Subject on the left, names on the right. Built so that a photograph and a
   paragraph can be added later without redesigning anything.
   -------------------------------------------------------------------------- */

.em-teachers { margin: var(--em-s-4) 0 0; }
.em-teachers > div {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: var(--em-s-2) var(--em-s-4);
  padding-block: var(--em-s-3);
  border-bottom: 1px solid var(--em-rule);
}
.em-teachers dt {
  font-size: var(--em-size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--em-sand-ink);
  padding-top: .3em;
}
/* The names are read as a list, not as a series of headings: body size, so
   they sit with the rest of the page's text, but Inter's Light so a column of
   fifteen of them stays quiet next to the subject labels. */
.em-teachers dd {
  margin: 0;
  font-size: var(--em-size-body);
  line-height: var(--em-lh-body);
  font-weight: 300;
}


/* --- Sibling navigation ---------------------------------------------------
   At the foot of a page, the other pages in the same part of the site. A
   visitor who arrived from Google on the Piano page has no other way to
   discover that the Corda page exists.
   -------------------------------------------------------------------------- */

.em-siblings { border-top: 1px solid var(--em-rule); padding-top: var(--em-s-3); margin-top: var(--em-s-6); }
.em-siblings p { font-size: var(--em-size-micro); letter-spacing: var(--em-track-kicker); text-transform: uppercase; color: var(--em-sand-ink); margin: 0 0 var(--em-s-2); }
.em-siblings ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--em-s-1) var(--em-s-3); }
.em-siblings a { color: var(--em-ink); text-decoration: none; font-size: var(--em-size-small); }
.em-siblings a:hover { color: var(--em-red); }
.em-siblings [aria-current] { color: var(--em-sand-ink); }


/* --- Cards ----------------------------------------------------------------
   The route card from the homepage, reused. --plain drops the artwork, for
   grids where twelve icons would be noise.
   -------------------------------------------------------------------------- */

.em-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--em-s-3); margin-top: var(--em-s-4); }
.em-cards--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.em-route--plain { padding-top: var(--em-s-3); }
.em-route__meta { font-size: var(--em-size-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--em-sand-ink); }


/* --- Forms ----------------------------------------------------------------
   Contact and the trial lesson. In WordPress these are the existing
   Contact Form 7 forms restyled, not a new plugin.
   -------------------------------------------------------------------------- */

.em-form { display: grid; gap: var(--em-s-3); max-width: 34rem; margin-top: var(--em-s-4); }
.em-form label { display: grid; gap: .4em; font-size: var(--em-size-small); }
.em-form .em-req { color: var(--em-red); }
.em-form input, .em-form textarea, .em-form select {
  font: inherit;
  font-size: var(--em-size-body);
  color: var(--em-ink);
  padding: .7em .8em;
  border: 1px solid var(--em-rule);
  border-radius: var(--em-radius);
  background: var(--em-white);
  width: 100%;
}
.em-form input:focus, .em-form textarea:focus, .em-form select:focus {
  outline: 2px solid var(--em-red);
  outline-offset: 1px;
  border-color: transparent;
}
.em-form textarea { min-height: 8rem; resize: vertical; }
.em-form label.em-form__consent {
  display: flex; gap: .7em; align-items: start;
  font-size: var(--em-size-small); color: var(--em-ink-60);
}
.em-form__consent input { width: auto; margin-top: .25em; flex: none; }
.em-form button { justify-self: start; }


/* A single column of content in an otherwise full-width section — a form, or a
   block of prose with nothing to sit beside it. */
.em-narrow { max-width: 46rem; }

/* --- Actualitat archive ---------------------------------------------------- */

.em-archive { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--em-s-5) var(--em-s-3); margin-top: var(--em-s-4); }
.em-filters { display: flex; flex-wrap: wrap; gap: var(--em-s-1); margin-top: var(--em-s-3); }
.em-filter {
  font-size: var(--em-size-small);
  padding: .35em .9em;
  border: 1px solid var(--em-rule);
  border-radius: var(--em-radius-pill);
  color: var(--em-ink);
  text-decoration: none;
  transition: background var(--em-transition), border-color var(--em-transition);
}
.em-filter:hover { background: var(--em-sand-12); border-color: var(--em-sand); color: var(--em-red-dark); }
.em-filter[aria-current] { background: var(--em-red); border-color: var(--em-red); color: var(--em-white); }


/* --- Responsive, part two -------------------------------------------------- */

@media (max-width: 900px) {
  .em-page__grid,
  .em-split,
  .em-split--narrow-right { grid-template-columns: minmax(0, 1fr); gap: var(--em-s-4); }
  .em-page__grid .em-sketch { max-width: 380px; }
  .em-cards, .em-archive { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .em-teachers > div { grid-template-columns: minmax(0, 1fr); gap: .3em; }
}

@media (max-width: 640px) {
  .em-cards, .em-cards--2, .em-archive { grid-template-columns: minmax(0, 1fr); }
  .em-sketch--pair { grid-template-columns: 1fr 1fr; gap: var(--em-s-2); }
  .em-facts { grid-template-columns: minmax(0, 1fr); gap: .3em var(--em-s-3); }
  .em-facts dd + dt { margin-top: var(--em-s-2); }
}


/* --- Activity entries -----------------------------------------------------
   Masterclasses, cursos and tallers. The school makes a poster for each one,
   so the poster is the post's featured image and it is shown here at a size
   you can actually read, with the text beside it. Nobody has to click through
   to Actualitat to find out when it is or how to sign up.
   -------------------------------------------------------------------------- */

.em-entries { display: grid; gap: var(--em-s-6); }
.em-entry {
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: var(--em-s-4);
  align-items: start;
}
.em-entry__poster {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--em-sand-12);
  border-radius: var(--em-radius);
  overflow: hidden;
}
/* Photographs of events that have happened: cropped to the common box, so a
   vertical photo zooms in rather than sitting in a letterbox. */
.em-entry__poster img { width: 100%; height: 100%; display: block; object-fit: cover; }
.em-entry__date {
  font-size: var(--em-size-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--em-sand-ink);
  margin: 0 0 var(--em-s-1);
}
.em-entry__body h3 { margin: 0 0 var(--em-s-2); }
.em-entry__body h3 a { color: inherit; text-decoration: none; }
.em-entry__body h3 a:hover { color: var(--em-red); }
.em-entry__body p:last-child { margin-bottom: 0; }

@media (max-width: 640px) {
  .em-entry { grid-template-columns: 1fr; gap: var(--em-s-3); }
  .em-entry__poster img { max-width: 320px; }
}

/* The pinned entry: the masterclass that has not happened yet. Larger poster,
   on the paper ground, so it is plainly the one you can still sign up for. */
.em-entry--pinned { grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: var(--em-s-5); }
.em-entry--pinned .em-entry__body h3 { font-size: var(--em-size-h2); font-family: var(--em-font-display); font-weight: 400; }
@media (max-width: 640px) { .em-entry--pinned { grid-template-columns: 1fr; } }

/* The upcoming section carries the page: bigger heading, more air around it,
   and more room between entries when several are announced at once. */
.em-upcoming { padding-block: var(--em-s-7); }
.em-upcoming .em-h2 {
  font-size: clamp(2.4rem, 1.5rem + 3.4vw, 3.75rem);
  max-width: 18ch;
}
.em-upcoming .em-entries { gap: var(--em-s-7); }

/* Any heading sitting directly on a list of entries needs room under it. */
.em-h2 + .em-entries { margin-top: var(--em-s-5); }
.em-upcoming .em-h2 + .em-entries { margin-top: var(--em-s-6); }
/* The pinned entry is an announcement and its image is a poster: shown whole,
   at its own shape, because the dates and the price are printed on it. */
.em-entry--pinned { gap: var(--em-s-5); align-items: center; }
.em-entry--pinned .em-entry__poster { aspect-ratio: auto; background: none; }
.em-entry--pinned .em-entry__poster img { height: auto; object-fit: contain; }

/* Post text keeps the paragraphs, list lines and links it was written with. */
.em-entry__body p { margin: 0 0 var(--em-s-2); }
.em-entry__body a { color: var(--em-red-dark); }

/* --- Month bands in the activities calendar -------------------------------
   The months are filled with the palest of the grid's tile tones, so the term
   reads as a few coloured bands rather than one long list of dates. The colour
   is the same --em-red-12 the .em-cell--faint tiles use.
   -------------------------------------------------------------------------- */

.em-table--bands .em-table__group th {
  background: var(--em-red-12);
  border-bottom-color: transparent;
  padding: var(--em-s-2);
  font-size: var(--em-size-small);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--em-ink);
}
/* the band runs the whole row, not just the first cell */
.em-table--bands .em-table__group td { background: var(--em-red-12); border-bottom-color: transparent; }
/* every row is inset to the same place the month starts */
.em-table--bands th:first-child,
.em-table--bands td:first-child { padding-left: var(--em-s-2); }
.em-table--bands .em-table__group + tr th,
.em-table--bands .em-table__group + tr td { padding-top: var(--em-s-2); }

/* A table whose columns explain themselves: the header row stays in the markup
   for screen readers and comes out of the visual flow. */
thead.em-sr { display: table-header-group; position: absolute; width: 1px; height: 1px;
              overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* A poster shown at its own proportions beside the text that introduces it. */
.em-poster { margin: 0; }
.em-poster img { width: 100%; height: auto; display: block; border-radius: var(--em-radius); }
