/**
 * @file
 * A deliberately small utility set. Anything used more than three times gets
 * promoted to a component instead.
 */

.u-hidden { display: none !important; }
.u-flow > * + * { margin-block-start: var(--space-s); }
.u-text-center { text-align: center; }
.u-text-muted { color: var(--text-muted); }
.u-text-secondary { color: var(--text-secondary); }
.u-accent { color: var(--text-accent); }
.u-nowrap { white-space: nowrap; }
.u-tabular { font-variant-numeric: tabular-nums; }
.u-mt-0 { margin-block-start: 0 !important; }
.u-mb-0 { margin-block-end: 0 !important; }
.u-mt-m { margin-block-start: var(--space-m); }
.u-mt-l { margin-block-start: var(--space-l); }
.u-mt-xl { margin-block-start: var(--space-xl); }
.u-full-bleed { grid-column: full; }
.u-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

@media (max-width: 47.999rem) {
  .u-hide-sm { display: none !important; }
}

@media (min-width: 48rem) {
  .u-show-sm-only { display: none !important; }
}


/* A view's "more" link, wherever it appears. */
.view__more a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  color: var(--text-accent);
  font-size: var(--step--1);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-decoration: none;
}

.view__more a::after {
  content: "→";
}

.view__more a:hover {
  text-decoration: underline;
}


/**
 * Views' RSS feed icon.
 *
 * Drupal's default `frontpage` view ships one, and it renders as the bare words
 * "Subscribe to" at the foot of whatever region the view is in — which is how
 * it appeared under the listing on the live front page. Styled as a small
 * action rather than left as loose text. (Better still: disable the default
 * frontpage view, see PAGE-SETUP.md.)
 */
.view__feed-icons {
  margin-block-start: var(--space-m);
}

.view__feed-icons a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  color: var(--text-muted);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-decoration: none;
}

.view__feed-icons a::before {
  content: "\2197";
}

.view__feed-icons a:hover {
  color: var(--text-accent);
}

/* ===========================================================================
 * THE ARCED FOOT, SHARED BY EVERY BANNER.
 *
 * The slideshow, the landing hero, the event hero and the hub hero all used to
 * end on a dead-straight horizontal line with a hairline under it. Four bands
 * doing the same thing is a system; four bands ending the same flat way is just
 * a series of rectangles, and on a site whose cards, panels and plates are all
 * rounded it was the one place the geometry disagreed with itself.
 *
 * They now end on a shallow convex arc: the band dips furthest into the page at
 * the centre and rises to nothing at the sides.
 *
 * WHY A BORDER-RADIUS AND NOT A MASK OR AN OVERLAY
 *
 * Three ways to cut this shape, and only one of them is safe here:
 *
 *  - an overlay in the page colour, scooping upward, needs whatever sits below
 *    to stay a flat colour forever. It does today. It would break silently the
 *    day a section below gets a background of its own.
 *  - an SVG mask gives a freer curve and takes the element out of the normal
 *    paint path; anything positioned against the band's edge then has to be
 *    reasoned about twice.
 *  - a border-radius is just the box. It composites with the backdrop already
 *    there, needs no second colour, and a browser that does not understand the
 *    elliptical syntax simply draws the flat edge it drew before.
 *
 * `50%` horizontally against a fixed vertical radius is what makes it an arc
 * across the whole width rather than two rounded corners with a flat run
 * between them: the two ellipses meet exactly at the centre.
 *
 * THE HAIRLINE GOES WITH IT. A 1px border follows the curve on the sides and
 * then cuts straight across underneath, which reads as a mistake; the arc is
 * its own edge.
 * ======================================================================== */
:root {
  --band-arc: 3rem;
}

@media (max-width: 47.999rem) {
  :root {
    /* A short banner on a phone cannot spare 48px of its height, and the curve
       reads steeper at a narrow width for the same radius. */
    --band-arc: 1.5rem;
  }
}

/*
 * THE SAME GESTURE AT COMPONENT SCALE — A SEPARATE, MUCH SMALLER NUMBER.
 *
 * `--band-arc` cannot be reused on a card. A 50% radius is half the element's
 * width, so the same 48px of depth spread across a 1400px band is a gentle
 * sweep and across a 340px card is a bulge four times as steep. Applied to
 * whole cards earlier it ate the first letter of every title.
 *
 * `--arc-sm` is the depth for anything inside the page container: the picture
 * at the top of a card, the heading band at the top of a side panel. Small
 * enough to read as the same family as the big arcs without deforming a box
 * that has content near its corners.
 *
 * It does not shrink on a phone. A card is roughly the same width at every
 * breakpoint — one column on a narrow screen, three on a wide one — so the
 * ratio that matters here barely moves.
 */
:root {
  --arc-sm: 0.875rem;
}

/*
 * EVERY FULL-BLEED BAND, AT PAGE SCALE.
 *
 * The slideshow and every page banner — the landing hero, the event hero, the
 * hub hero, the interior page band, the submission band and the 403/404 band.
 * Each one is the thing at the top of its page, so each ends the same way.
 *
 * The error band belongs here for a reason beyond consistency: an error page
 * that is built like every other page is an answer, while one that is built
 * slightly differently looks like a second failure on top of the first.
 *
 * NOT THE HEADER. It was tried twice and taken off twice, and the reason is
 * recorded here so it is not tried a third time: the bar is sticky, so its edge
 * is on screen for the whole visit, and a shaped edge that is always present
 * stops being a gesture and becomes the shape of the site. These arcs read as
 * punctuation precisely because they arrive and leave.
 *
 * To add another full-bleed band, put its selector here. The depth, the
 * overflow and the removed hairline all follow from this rule.
 */
.slider,
.hero,
.event-hero,
.hub-hero,
.page-hero,
.form-intro,
.error-band {
  border-end-start-radius: 50% var(--band-arc);
  border-end-end-radius: 50% var(--band-arc);

  /* Required for the radius to actually clip a picture inside the band; without
     it the artwork simply overhangs the curve. */
  overflow: hidden;

  /* The arc is the edge now. */
  border-block-end: 0;
}

/*
 * THE FOOTER TAKES THE SAME CURVE, MIRRORED.
 *
 * The slideshow's arc is on its FOOT and bulges down into the page. The
 * footer's is on its HEAD and is scooped the same way — the page dips down into
 * it. Same depth, same token, bending in the same direction, so the two read as
 * one gesture opening and closing the document.
 *
 * Curving the footer this way also avoids a pinch: were it bulging upward while
 * the slideshow droops down, the column between them would be narrowest in the
 * middle. Never visible in practice — they are a page apart — but it is one
 * less thing to be true.
 *
 * The hairline above the footer goes for the same reason the banners' went: a
 * 1px border follows the curve and then cuts straight across, and the curve is
 * its own edge.
 *
 * This reads because the footer is `--surface-1` against an `--me-ink` canvas.
 * If the two were ever set to the same colour the curve would be invisible and
 * this rule would be dead weight.
 */
.site-footer {
  /*
   * INWARD, AND SO DRAWN WITH A MASK RATHER THAN A RADIUS.
   *
   * A `border-radius` can only round a corner away, which makes the footer
   * bulge UP at its centre — outward. Curving the other way means taking a bite
   * out of the top edge, and a box cannot be given a concave corner.
   *
   * Two ways to bite: an ellipse painted in the page colour over the footer's
   * head, or a mask. The overlay is simpler and ties the footer to whatever
   * colour happens to be above it — fine today, wrong the moment a section
   * above it gets a background. The mask cuts the shape out of the footer
   * itself, so it composites against anything.
   *
   * The gradient is a hard-edged ellipse: transparent inside, opaque outside,
   * with both stops at 100% so there is no feathering. `50%` wide against
   * `--band-arc` tall gives the same sweep the banners have, in the opposite
   * direction — so every curve on the page now bends the same way, and the
   * banner's foot and the footer's head read as one rhythm rather than as two
   * facing brackets.
   *
   * A browser without mask support draws the flat edge it drew before, which is
   * the same graceful failure the banners have.
   */
  -webkit-mask-image: radial-gradient(50% var(--band-arc) at 50% 0%, transparent 100%, #000 100%);
  mask-image: radial-gradient(50% var(--band-arc) at 50% 0%, transparent 100%, #000 100%);
  border-block-start: 0;
}

/*
 * ROOM FOR THE CURVE, ON THE FOOTER ITSELF.
 *
 * Padding is measured from the box's top edge, and the bite is taken out below
 * that line — so the deepest point of the scoop is `--band-arc` down, at the
 * centre. A full arc of padding is exactly what it takes to clear it.
 *
 * It goes on the footer rather than on `.site-footer__top`, which was the first
 * attempt: that only helps a footer that HAS the three-column block. A page
 * whose footer is just the link bar — most of them — got nothing, and the links
 * ran straight under the curve.
 */
.site-footer {
  padding-block-start: var(--band-arc);
}

/*
 * THE SLIDE'S CONTENTS RISE WITH THE ARC — ALL OF THEM, TOGETHER.
 *
 * The slideshow's dots, pause and arrows sit at the foot of the band, and the
 * caption plate sits above them with a measured gap. Both have to clear the
 * curve now.
 *
 * The first attempt lifted only the control row, with a `margin-block-end` on
 * an absolutely positioned element — which does move it, and moved it straight
 * into the bottom edge of the plate. The plate's own padding already reserved
 * exactly enough room for a control row 16px off the floor; raising the row and
 * not the plate closed that gap to nothing.
 *
 * So both offsets get `--band-arc` added, and the 52px between them is
 * preserved. The composition is identical, sitting higher by the depth of the
 * curve — which is right, because that much of the band's foot is no longer
 * there to sit on.
 *
 * `inset-block-end` rather than a margin: it is the property the component
 * already uses to place these, so there is one way this row is positioned
 * rather than two interacting ones.
 */
/*
 * THE SLIDESHOW'S OWN OFFSETS HAVE GONE FROM HERE.
 *
 * Two rules used to live at this spot: one lifting `.slider__controls` clear
 * of the arc, and one reserving room for that row inside `.slide__body`. Both
 * belonged to the overlay slideshow — a caption plate lying on the picture
 * with the controls floating over its foot — and that layout no longer exists.
 * The slide is a picture with a bar of words beneath it; the bar carries the
 * arc's clearance in its own padding and the control row sits inside the
 * picture. Both are stated in css/components/slider.css, where the rest of the
 * slide's geometry is.
 *
 * LEAVING THEM HERE WAS NOT HARMLESS. `inset-block-end` here plus
 * `inset-block-start` there gave the control row BOTH insets, so instead of
 * being its own height it stretched to fill the gap between them — a 30px row
 * reported as 162px, hanging out of the bottom of the picture.
 */

/*
 * The listing card's picture, over the card's body.
 *
 * THIS CAME OFF AND WENT BACK ON. Worth recording both moves, because the arc
 * was blamed for something it was not doing.
 *
 * A curve is drawn by clipping the element to it, so the foot of every
 * thumbnail genuinely is cut away by up to --arc-sm at its centre — and while
 * `object-fit` was also trimming the picture to a box of the wrong shape,
 * that clipping was the visible half of a problem with two causes. Fixing the
 * shape fixed the cropping; the arc was never the part that mattered, and the
 * join between a card's picture and its body is exactly where this theme's
 * arc belongs.
 *
 * What it costs is a few pixels of the picture's bottom edge at the centre.
 * That is a deliberate trade, not an oversight.
 */
.event-card__media {
  border-end-start-radius: 50% var(--arc-sm);
  border-end-end-radius: 50% var(--arc-sm);

  /* The picture has to be clipped to the curve, not merely sat behind it. */
  overflow: hidden;
}

/*
 * The panel heading band.
 *
 * Its top corners already follow the panel's own radius, because the band is
 * pulled out to the panel's edges and the panel clips. Only the foot is shaped
 * here, so the band hangs into the panel exactly as a card's picture hangs into
 * its body.
 */
.panel__title {
  border-end-start-radius: 50% var(--arc-sm);
  border-end-end-radius: 50% var(--arc-sm);
}

/*
 * The newsletter panel — the one exception to "internal joins only".
 *
 * It has no internal seam: one surface, copy on the left and the form on the
 * right. So the arc goes on its own foot, which is the thing this file
 * otherwise avoids — a shaped edge on a floating box rather than on a join.
 *
 * It earns the exception on proportion. The panel is about 1450px wide, so
 * `--arc-sm` across it is nearly as shallow as `--band-arc` across the
 * viewport: the same gentle sweep, not the bulge the same radius would make of
 * a 340px card.
 *
 * `--band-arc` was tried here and is too much — at 48px the panel stops reading
 * as a card and starts reading as a tab or a lozenge, and its straight top edge
 * makes the asymmetry obvious. At `--arc-sm` the curve is quiet enough to be
 * felt rather than noticed, which is the whole point of it.
 */
.subscribe {
  border-end-start-radius: 50% var(--arc-sm);
  border-end-end-radius: 50% var(--arc-sm);
}
