/* The public site. Plain on purpose: feature 002 replaces this against the
   wireframes, and everything it needs from here is structure rather than
   styling (S02).

   Styles an admin can apply carry an @style annotation. The comment has to sit
   directly above its rule; label and target are separated by a pipe. The
   target is the element the style belongs on. */

/* The brand, taken straight out of the 2024 logo (RGB web SVG): navy carries
   the structure, the bright blue marks what is active or clickable, the sky
   tint is for quiet surfaces. The teal of the old site is deliberately gone -
   the new logo has no teal in it.

   Custom properties so 002 can restyle without hunting for hex codes. */
:root {
    --navy: #003489;
    --navy-dark: #002766;
    --blue: #009fe3;
    --blue-dark: #0d84bb;
    --sky: #5bc5f2;
    --tint: #e8f4fb;
    /* One step down from the tint, for anything that has to read on top of it. */
    --tint-deep: #d5e8f4;
    --ink: #222;
    --muted: #666;
    --line: #e5e5e5;

    /* The header's own band, hsl(209 52% 84%), with its hover five points of
       lightness below it. Deeper than --tint because .hero-band is --tint and
       sits directly under the header, and at the same weight the two read as
       one block with a navy line drawn through them. As deep as it goes while
       staying bright: the logo is navy on transparent with no negative
       version, and it carries 7.7:1 here. */
    --header: #c1d7eb;
    --header-hover: #aecae5;

    /* The column every page is laid out in. */
    --wrap: 1200px;

    /* Two roundings, because they are two decisions and not one: anything you
       click is rounded, anything you look at is barely rounded at all. Named
       rather than typed out, so "soften the corners" is one line and not eleven,
       and so a new rule picks a side instead of a number (002/S01).
       The control side is the rounder of the two on purpose - a button that
       reads as a button is worth more than a panel that reads as a card. */
    --radius-control: 6px;
    --radius-panel: 4px;
}

* { box-sizing: border-box; }

/* The page is a column as tall as the window at least, and main takes what is
   left over. A short page therefore puts the footer against the bottom edge
   instead of leaving a band of background under it, and a long one leaves it
   where it falls, after the content, reached by scrolling. Neither case needs
   the footer to be fixed or to know anything about the content above it. */
body {
    margin: 0;
    font-family: system-ui, sans-serif;
    line-height: 1.55;
    color: var(--ink);
    background: #fff;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

main { flex: 1 0 auto; }
footer { flex: none; }

.wrap {
    max-width: var(--wrap);
    margin: 0 auto;
    padding: 0 1rem;
}

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

.site-header {
    padding: 1.25rem 0;
    background: var(--header);
    border-bottom: 4px solid var(--navy);
}

/* Logo, then the menu starting beside it and running on to the right, rather
   than pushed against the far edge. */
.site-header .wrap {
    display: flex;
    align-items: center;
    gap: 3rem;
}

.site-header .logo {
    display: inline-block;
    line-height: 0;
    flex: none;
}

.site-header nav {
    flex: 1 1 auto;
}

.site-header .logo img {
    height: 84px;
    width: auto;
}

/* The button the menu hides behind below 820px. Off the page entirely where
   the menu fits beside the logo, and pushed to the far edge of the row where
   it does not: the thumb that reaches for it comes from the side, not from
   the middle. */
.site-header .burger {
    display: none;
    flex: none;
    margin-left: auto;
    padding: .4rem;
    border: 0;
    border-radius: var(--radius-control);
    background: none;
    color: var(--navy);
    line-height: 0;
    cursor: pointer;
}

.site-header .burger:hover { background: var(--header-hover); }

/* One SVG, two icons, and the class on the header decides which. */
.site-header .burger .burger-cross,
.site-header.menu-open .burger .burger-bars { display: none; }

.site-header.menu-open .burger .burger-cross { display: inline; }

/* ------- Navigation

   Navy text on the header's band: no boxes, no dividers, no underlines. Space
   separates the entries and hovering darkens one a step.
   The current page is filled navy with white text - a pale fill was too close
   to the header behind it to read as "you are here", and reversing the colours
   carries at a glance. */

.site-header nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
}

.site-header nav a {
    display: block;
    padding: .45rem 1.1rem;
    color: var(--navy);
    text-decoration: none;
    font-weight: 600;
    font-size: 1.1rem;
    transition: background-color .12s ease, color .12s ease;
}

.site-header nav a:hover,
.site-header nav a:focus-visible {
    background: var(--header-hover);
    color: var(--navy);
    text-decoration: none;
}

.site-header nav a[aria-current="page"] {
    background: var(--navy);
    color: #fff;
    font-weight: 700;
    border-radius: var(--radius-control);
}

/* Hovering the page you are already on changes nothing: it is not somewhere to
   go. */
.site-header nav a[aria-current="page"]:hover {
    background: var(--navy);
    color: #fff;
}

/* ------- Content */

main { padding: 2rem 0 4rem; }

main img { max-width: 100%; height: auto; }

h1 {
    font-size: 2.25rem;
    line-height: 1.15;
    margin: 0 0 1.5rem;
    color: var(--navy);
}

h2 { font-size: 1.5rem; line-height: 1.25; margin: 2rem 0 .75rem; color: var(--navy); }
h3 { font-size: 1.2rem; margin: 1.5rem 0 .5rem; color: var(--navy); }
p  { margin: 0 0 1rem; }

a {
    color: var(--navy);
    text-decoration: none;
}

a:hover {
    color: var(--blue);
    text-decoration: underline;
}

.draft-notice {
    background: #fff6d8;
    border: 1px solid #e6cf7a;
    padding: .75rem 1rem;
    margin: 0 0 1.5rem;
}

footer {
    border-top: 4px solid var(--blue);
    background: var(--navy);
    padding: 2rem 0;
    color: #dbe3f5;
    font-size: .9rem;
}

/* The footer menu. Same source as the header's, a different set of pages. */
footer nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem 1.75rem;
}

footer nav a {
    color: #fff;
    font-weight: 600;
}

footer nav a:hover { color: var(--sky); }

footer nav a[aria-current="page"] { text-decoration: underline; }

/* ------- Hero

   An image placed at the very top of a page becomes its banner, above the
   title: full content width, cropped to a band rather than however tall the
   file happens to be. Nothing is stored for this and nothing is configured -
   the admin decides by putting an image first, and undoes it by putting
   anything above it. page_hero_split() lifts it out of the content. */

/* Flush against the header and as wide as the window. No radius: a band that
   reaches both edges has no corners to round. */
.hero {
    margin: 0;
    line-height: 0;
    height: 21rem;
    overflow: hidden;
}

/* The image keeps its own proportions and is pushed up by --hero-top, which the
   admin set by dragging it (`src/admin/edit.php`). The unit is what makes this
   hold: a percentage margin resolves against the width of the containing block,
   and the image's height is that same width times its aspect ratio, so the two
   scale together. Whatever the admin put against the top edge stays against the
   top edge in every window, and a taller or shorter band only changes how much
   is cut off underneath.

   object-fit and min-height are for the other case: an image too short to fill
   the band, which would otherwise leave a strip of background under it. */
.hero img {
    display: block;
    width: 100%;
    height: auto;
    min-height: 100%;
    object-fit: cover;
    margin-top: calc(-1 * var(--hero-top, 0%));
}

@media (max-width: 820px) {
    .hero { height: 12rem; }
}

/* ------- Styles an admin can apply (S15) */

/* @style Quote | p */
.quote {
    border-left: 4px solid var(--blue);
    padding-left: 1.25rem;
    color: var(--navy);
    font-size: 1.15rem;
}

/* Not annotated: with one content field there is no block to apply it to (D21). */
.highlight {
    background: var(--tint);
    padding: 1.75rem;
    border-radius: var(--radius-panel);
}

/* Every button on this site is this shape. It used to carry .btn beside it, the
   class plan-your-events' script wrote on "To the registration" while the
   webinar board was drawn in the browser; that board is rendered here now
   (003/D4) and writes .button like everything else. */
.button,
.button-quiet {
    display: inline-block;
    padding: .5em 1.4em;
    text-decoration: none;
    border-radius: var(--radius-control);
    font-weight: 600;
}

/* @style Button | a */
.button {
    background: var(--blue);
    color: #fff;
}

.button:hover { background: var(--navy); color: #fff; }

/* @style Button, quiet | a */
.button-quiet {
    background: var(--tint);
    color: var(--navy);
}

.button-quiet:hover { background: var(--tint-deep); color: var(--navy); }

/* @style Lead paragraph | p */
.lead {
    font-size: 1.3rem;
    line-height: 1.5;
    color: var(--muted);
}

/* Not annotated, so not offered in the editor: internal helpers. */
/* The mark on a link that leaves this site. Sized in ems so it tracks whatever
   it sits beside, and nudged up because a glyph's optical middle is above the
   baseline the box would put it on. Quieter than the words: it qualifies the
   link rather than competing with it. */
.icon-external {
    margin-left: .3em;
    vertical-align: -.08em;
    opacity: .65;
}

a:hover .icon-external { opacity: 1; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

/* ------- Phone

   The menu goes behind a button and stacks when it is opened, so every entry
   stays a full-width target rather than a cramped row of words. */

@media (max-width: 820px) {
    .site-header { padding: 1rem 0; }
    .site-header .logo img { height: 60px; }

    /* Side by side stops fitting: the logo and the button share the row and
       the menu wraps under both of them at full width. Wrapping rather than a
       column, because the button belongs beside the logo. */
    .site-header .wrap {
        flex-wrap: wrap;
        gap: 1rem;
    }

    .site-header nav { flex-basis: 100%; }

    /* Both halves of this wait on the script: without it the button would open
       nothing, so it is not shown and the menu stays where it is. Opening it
       pushes the page down rather than covering it (002/S01). */
    .js .site-header .burger { display: block; }
    .js .site-header nav { display: none; }
    .js .site-header.menu-open nav { display: block; }

    .site-header nav ul { display: block; }

    .site-header nav li + li { border-top: 1px solid var(--line); }

    /* Stacked entries do need something between and beside them: a bar on the
       left is the marker here, not an underline. */
    .site-header nav a {
        padding: .6rem .75rem;
        border-left: 4px solid transparent;
    }

    .site-header nav a:hover,
    .site-header nav a[aria-current="page"] { border-left-color: var(--blue); }

    h1 { font-size: 1.75rem; }
}

/* ------- The committee (002/S10)

   A list of people an admin keeps, printed under the text of the page that
   asks for it. Cards rather than a table: the old site laid this out in twelve
   nested tables, which is what made it unmaintainable. */

.committee {
    margin: 2.5rem 0 0;
    border-top: 1px solid var(--line);
    padding-top: 2rem;
}

.committee ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* A row per member: the portrait and the four lines under it in a fixed left
   column, the biography in what is left. Fixed rather than a fraction so that
   twelve portraits line up down the page - a column that sized itself to its
   own text would step in and out beside a name of three words and a name of
   eight.

   As narrow as the portrait it holds: everything written about a member sits in
   the second column now, so the first has one job. */
.committee li {
    display: grid;
    grid-template-columns: 8.5rem 1fr;
    gap: 0 2rem;
    padding: 2rem 0;
    border-bottom: 1px solid var(--line);
}

.committee li:last-child { border-bottom: 0; }

/* Second column by rule rather than by order: a member with no portrait emits
   no first cell, and grid would slide their text under the pictures. */
.committee-person { grid-column: 2; }

/* Round, and always the same size whatever was uploaded. A portrait is missing
   rather than grey when there is none: the element is not rendered at all. */
.committee img {
    width: 8.5rem;
    height: 8.5rem;
    object-fit: cover;
    border-radius: 50%;
    margin: 0;
    display: block;
}

/* The portrait as a link, where that member has a profile. No underline and no
   link colour - it is a picture, and dimming it on hover is what says it can be
   clicked.

   start on both axes, and the radius, because the link is a grid item: left to
   itself it stretches to the full height of the row and the whole empty column
   under the portrait becomes clickable. It ends where the picture ends. */
.committee-portrait {
    display: block;
    line-height: 0;
    align-self: start;
    justify-self: start;
    border-radius: 50%;
}
.committee-portrait:hover { text-decoration: none; }
.committee-portrait img { transition: opacity .12s ease; }
.committee-portrait:hover img,
.committee-portrait:focus-visible img { opacity: .85; }

.committee p { margin: 0; }

/* Heading the text under it rather than captioning the picture beside it, so a
   step up from the lines it introduces. */
.committee .committee-name { font-weight: 700; font-size: 1.15rem; color: var(--navy); }
.committee .committee-function { color: var(--blue-dark); }
/* Italic, and held to its own measure. Without both it reads as the first line
   of the biography under it: same muted grey, nearly the same size, parted only
   by a margin. */
.committee .committee-affiliation {
    font-size: .9rem;
    font-style: italic;
    color: var(--muted);
    margin-top: .25rem;
    max-width: 34rem;
}

.committee a { font-size: .9rem; }

/* Set quieter than the three lines above it: it is the longest thing on the
   page and the eye should land on who somebody is first.
 *
 * 38rem is about 75 characters at this size. The column it sits in is far wider
 * on a desktop, and a 110-character line is measurably harder to read - the eye
 * loses the start of the next one. Capping the text is what shortens the line;
 * splitting the page into two columns of members would do it too, but this list
 * is ranked - president, vice president, treasurer - and two columns make that
 * order something the reader has to work out. */
.committee-bio {
    margin-top: .9rem;
    font-size: .95rem;
    color: var(--muted);
    max-width: 38rem;
}

/* .committee p above zeroes every margin, which is right for the three label
   lines and wrong for prose: without this the paragraphs run into one block. */
.committee-bio p + p { margin-top: .7rem; }

@media (max-width: 820px) {
    /* One column: a portrait beside a paragraph of text is two columns too
       narrow to be either. */
    .committee li {
        grid-template-columns: 1fr;
        gap: 1rem 0;
        padding: 1.5rem 0;
    }

    .committee-person { grid-column: 1; }

    /* Bigger here than on the desktop, and centred rather than tucked left:
       once the row is stacked there is nothing beside the portrait to line it
       up with, and it becomes the thing that separates one member from the
       next. The text under it stays left - prose is read from an edge. */
    .committee img {
        width: 10rem;
        height: 10rem;
        margin: 0 auto;
    }

    /* The margin above centres the picture in its column; a link around it is
       what the column now holds, so it is the link that has to be centred. */
    .committee-portrait { justify-self: center; }
}

/* ------- Boards (003/D1)

   A designed section printed under a page's own text. The webinars inside are
   this site's own markup, read server side (003/D4) - there is nothing here
   from plan-your-events but the pictures. */

.board { margin: 2.5rem 0 0; }

.board h2 {
    border-top: 1px solid var(--line);
    padding-top: 1.5rem;
}

/* Read, and nothing is scheduled. Quiet and not shaped like anything to click,
   the same treatment .hero-note gets for the button that is not there yet. */
.board-empty {
    color: var(--muted);
    font-style: italic;
}

/* ------- Webinars, upcoming (003/S03)

   The same two columns the home page's hero band puts a webinar in - what it is
   on the left, who is giving it on the right - because it is the same webinar
   and a visitor may well have arrived here from that band. */

.webinars {
    list-style: none;
    margin: 0;
    padding: 0;
}

.webinar {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem 2.5rem;
    align-items: flex-start;
    padding: 1.5rem 0;
    border-bottom: 1px solid var(--line);
}

.webinar:last-child { border-bottom: 0; }
.webinar-text { flex: 1 1 55%; }
.webinar .speakers { flex: 1 1 30%; }

.webinar-text h3 { margin: .1rem 0 .5rem; }
.webinar-description p:first-child { margin-top: 0; }
.webinar-description p:last-child { margin-bottom: 0; }

/* Where it is and when, above the title: the two things somebody scanning a
   list of webinars sorts on. */
.webinar-meta {
    margin: 0;
    font-size: .9rem;
    color: var(--muted);
}

/* ------- Webinars, the archive (003/D11)

   All of them, newest first, as a table: a date in its own column and the
   webinar in the second. This is the shape the old site gave these and the
   shape sixteen of them want - a list somebody runs their eye down looking for
   one country or one year, rather than sixteen blocks each asking to be read.

   Nothing in here is a picture. The portraits belong on the webinar somebody is
   deciding whether to attend, and a thumbnail of the first slide only says
   "this is a slide deck", which the words already said. */

.webinars-past {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Three columns, and the last one a fixed width rather than sized to whatever
   that row happens to hold: a table where the titles start in the same place on
   every row but end in a different one is not read as a table. Rows whose
   speakers sent no photograph leave it empty, which is what an empty cell is
   for. */
.webinars-past > li {
    display: grid;
    grid-template-columns: 9.5rem 1fr 8.5rem;
    gap: 0 1.5rem;
    padding: .85rem 0;
    border-bottom: 1px solid var(--line);
}

.webinars-past > li:last-child { border-bottom: 0; }

/* The column that makes it a table. Its own line height, so a date sits level
   with the title beside it rather than with the top of the row. */
.webinar-date {
    margin: 0;
    color: var(--muted);
    font-size: .9rem;
    line-height: 1.6;
}

.webinars-past h4 {
    margin: 0;
    font-size: 1.05rem;
    line-height: 1.4;
    color: var(--navy);
}

.webinars-past h4 a { text-decoration: none; }
.webinars-past h4 a:hover { text-decoration: underline; }

.webinar-speakers {
    margin: .1rem 0 0;
    font-size: .9rem;
    color: var(--muted);
}

/* The faces that gave the webinar, in the last column. Small, and the same 3:4
   rounded rectangle the portraits have everywhere else on this site, so they
   read as the same people seen from further away rather than as a different
   kind of thing. They wrap, because one webinar had six speakers. */
.webinar-portraits {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
    align-content: start;
}

.webinar-portraits img {
    display: block;
    width: 2.25rem;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: var(--radius-panel);
}

/* The year the group under it happened in. A heading rather than something to
   be read off sixteen dates, because the year is what anybody remembers about a
   past webinar besides the country. */
.webinar-year {
    border-top: 0;
    padding-top: 0;
    margin: 1.75rem 0 .25rem;
    font-size: 1.1rem;
    color: var(--muted);
    letter-spacing: .04em;
}

.webinar-year:first-of-type { margin-top: 1rem; }

@media (max-width: 640px) {
    .webinar { gap: 1rem; }
    .webinar .speakers { flex-basis: 100%; }

    /* The date column stops being a column and becomes the line above, and the
       faces fall in under the webinar they gave rather than beside it. */
    .webinars-past > li { grid-template-columns: 1fr; gap: .15rem; }
    .webinar-portraits { margin-top: .4rem; }
}

/* ------- The home page (002/S02)

   Full-width bands, alternating between white and the sky tint over the
   sections that actually rendered - an empty section emits nothing at all, so
   the shading is decided by position rather than by which section it is. */

/* No padding of its own: every band brings its own, and a gap under the last
   one would read as an empty section between it and the footer. */
main.bands { padding: 0; }

.band { padding: 3.5rem 0; }
.band-tint { background: var(--tint); }
.band-plain { background: #fff; }

.band h2 {
    margin: 0 0 2rem;
    text-align: center;
    font-size: 2rem;
}

/* ------- The hero bands (002/S04)

   One per thing being announced, stacked, earliest first, and the mission band
   when there is nothing. Full width, against the header. */

.hero-band {
    background: var(--tint);
    border-bottom: 1px solid #d3e6f3;
    padding: 3rem 0;
}

.hero-band h1 { margin: 0 0 1rem; }

.hero-meta {
    margin: 0 0 .5rem;
    color: var(--blue-dark);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .85rem;
}

.hero-band-inner {
    display: flex;
    align-items: center;
    gap: 3rem;
}

.hero-band-text { flex: 1 1 55%; }

/* The right column, the same 45% the conference band gives its picture: no
   band has both. */
.hero-band-inner > .speakers { flex: 1 1 45%; }
.hero-text p:last-child { margin-bottom: 0; }

/* The picture keeps its own proportions and is pushed up by --hero-top, the
   same rule the page banner uses; here it is a panel rather than a full-width
   band, so the crop is what makes different photographs sit the same. */
.hero-band-image {
    flex: 1 1 45%;
    height: 20rem;
    overflow: hidden;
    border-radius: var(--radius-panel);
}

.hero-band-image img {
    display: block;
    width: 100%;
    height: auto;
    min-height: 100%;
    object-fit: cover;
    margin-top: calc(-1 * var(--hero-top, 0%));
}

/* Nothing to announce: the society in one paragraph, centred. With a picture
   behind it the words move onto a half-transparent panel, so they stay
   readable whatever the photograph does underneath. */
.hero-mission { text-align: center; }
.hero-mission .wrap { max-width: 52rem; }
.hero-mission p { font-size: 1.15rem; }
.hero-mission h1 { font-size: 2.6rem; }

.hero-mission.has-photo {
    position: relative;
    padding: 5rem 0;
    border-bottom: 0;
}

/* Behind the words, cropped by the same rule as every other picture on the
   site: the point put at the top edge stays there at every window size. */
.hero-photo {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: var(--navy);
}

.hero-photo img {
    display: block;
    width: 100%;
    height: auto;
    min-height: 100%;
    object-fit: cover;
    margin-top: calc(-1 * var(--hero-top, 0%));
}

.hero-mission.has-photo .wrap { position: relative; }

.hero-panel {
    background: rgba(255, 255, 255, .88);
    border-radius: var(--radius-panel);
    padding: 2.5rem 2rem;
}

/* Without a picture there is nothing to sit on and nothing to keep apart. */
.hero-mission:not(.has-photo) .hero-panel { background: none; padding: 0; }

@media (max-width: 820px) {
    .hero-mission.has-photo { padding: 2.5rem 0; }
    .hero-mission h1 { font-size: 1.9rem; }
    .hero-panel { padding: 1.5rem 1.25rem; }
}

/* Who is presenting a webinar (002/S07, 003/S03). Two places show this list -
   the home page's hero band and the upcoming webinars on the board - so it is
   one class, and only the width it takes inside the band is the band's.

   Portraits at 3:4 and lightly rounded, which is how plan-your-events publishes
   them and how its own event page prints them: someone following a link from
   there finds the same faces cropped the same way. The names keep this site's
   navy, because they are the site's own text and not a quotation. */
.speakers {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    /* Tracks capped at the width a portrait is actually drawn at, rather than
       1fr: with 1fr two speakers in a wide column get half of it each and stand
       at opposite ends of a gap. Capped and centred, they stay beside each
       other however much room there is. */
    grid-template-columns: repeat(auto-fit, minmax(7rem, 11rem));
    justify-content: center;
    justify-items: center;
    gap: 1.25rem 1rem;
}

/* Capped, so two speakers in a wide column stay portraits rather than becoming
   the picture the conference band puts here. */
.speakers li { max-width: 11rem; text-align: center; }

/* Every column has a picture in it - a portrait, or that system's own stand-in
   for a speaker who has not sent one - so they are all the same box and the
   names underneath sit in a line. */
.speakers img {
    width: 100%;
    aspect-ratio: 3 / 4;
    border-radius: var(--radius-panel);
    display: block;
    margin-bottom: .5rem;
    /* Whatever shape the file turns out to be, it fills the same rectangle. */
    object-fit: cover;
}

.speakers p { margin: 0; }
.speakers .speaker-name { font-weight: 700; color: var(--navy); }
.speakers .speaker-title { font-style: italic; font-size: .9rem; color: var(--muted); }

/* Standing in for the button that is not there yet: quiet, and not shaped like
   anything to click. */
.hero-note {
    margin: 1.5rem 0 0;
    color: var(--muted);
    font-style: italic;
}

.buttons {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin: 1.5rem 0 0;
}

.hero-mission .buttons { justify-content: center; }

/* ------- Sections made of the same three shapes */

/* Picture beside text: the membership block and the contact block. */
.split {
    display: flex;
    align-items: center;
    gap: 3rem;
}

.split > * { flex: 1 1 50%; }

.split-image {
    display: block;
    width: 100%;
    height: 20rem;
    object-fit: cover;
    border-radius: var(--radius-panel);
}

.benefits { margin: 0 0 0 1.1rem; padding: 0; }
.benefits li { margin-bottom: .5rem; }

/* ------- The member map (002/S08)

   teamhub's map of the world, inlined so it can be coloured from here, with a
   band class on every country that has members. Three shades and nothing else:
   the section answers where the society is represented, not how many are in
   each place.

   The shapes are one file nobody maintains, which is what a map of the world
   can be. Everything about how it looks is here rather than in it. */

/* The claim the section is actually making, in words, as the map's caption. */
.map-count {
    margin: 1rem 0 0;
    text-align: center;
    color: var(--blue-dark);
    font-weight: 600;
}

.world-map-frame {
    margin: 1.5rem 0 0;
    /* The map is 2000 by 857 and the column is 1200: it scales down, and on a
       phone it would scale to a strip. Kept as wide as the column and no
       taller than a screen's worth. */
    max-width: 100%;
}

.world-map {
    display: block;
    width: 100%;
    height: auto;
    /* Land without members. Grey rather than the white of the band behind it,
       so the world has a shape of its own before anything is filled in. */
    fill: #ececec;
    /* Which is what the borders separate, so they are white: a hairline of the
       background drawn between one grey country and the next. */
    stroke: #fff;
    stroke-width: .7;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* One shade for a country with members: the header's soft blue carried two
   steps further down its own hue, to 1.84 against the grey land. The header's
   own value sat at 1.25 there and left Belgium and Sri Lanka looking like an
   artefact of the outline rather than a fill; a map is read at country size,
   not at the size of a navigation bar.

   Its own value rather than a header token, because it is no longer the
   header's colour: past --header-hover the two stop being the same decision.

   No scale, by decision rather than by omission (src/map.php: MAP_CLASS). The
   white outlines between countries are what keep Belgium, the Netherlands,
   France and Germany from merging into one shape, and how many separate
   countries there are is the point being made. */
.world-map .has-members { fill: #8bb4da; }

/* Cards: Learn more about ACP-i. */
.cards {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 1.5rem;
}

/* No padding on the card itself: the picture is flush to the top and both
   sides, so the padding belongs to the words underneath it (.card-body). A
   column, so a card with no picture is only its words and still fills the row
   at the same height as its neighbours. */
.cards a {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius-panel);
    text-align: center;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.band-plain .cards a { background: var(--tint); border-color: transparent; }

.cards a:hover {
    border-color: var(--blue);
    box-shadow: 0 2px 10px rgba(0, 52, 137, .08);
    text-decoration: none;
}

/* The top half of the card, corner to corner. A fixed height rather than a
   share of the card, because the cards are as tall as the longest of them and a
   proportional picture would be a different size in each: one straight edge
   across all three is what makes them read as a row. */
.cards img {
    width: 100%;
    height: 9rem;
    object-fit: cover;
    display: block;
}

.card-body { padding: 1.5rem; }

.card-title { font-weight: 700; font-size: 1.15rem; color: var(--navy); margin: 0 0 .35rem; }
.card-text { color: var(--muted); margin: 0; }

/* News cards (002/S06): the home page's three and the whole of /news, drawn the
   same way so the index reads as the section continued rather than as a second
   design of it.

   Not .cards: those are three round portraits with centred text, and a news
   item is a dated report with a photograph of something that happened. Picture
   across the top, text left, so a teaser of two lines starts where the eye
   already is. */
.news-cards {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: 1.5rem;
}

.news-cards a {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius-panel);
    transition: border-color .12s ease, box-shadow .12s ease;
}

.band-plain .news-cards a { background: var(--tint); border-color: transparent; }

.news-cards a:hover {
    border-color: var(--blue);
    box-shadow: 0 2px 10px rgba(0, 52, 137, .08);
    text-decoration: none;
}

/* A fixed height whatever was uploaded, so a row of cards has one top edge for
   its titles rather than three. */
.news-cards img {
    width: 100%;
    height: 11rem;
    object-fit: cover;
    display: block;
}

.news-card-text { padding: 1.25rem 1.25rem 1.5rem; }

.news-date {
    margin: 0 0 .35rem;
    color: var(--blue-dark);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .8rem;
}

/* Nothing in the menus points at /news, so an item found through a search
   result would otherwise be a dead end. */
.news-back { margin: 2.5rem 0 0; }

/* Quotes: what other members say. */
.quotes {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    column-gap: 2.5rem;
    row-gap: 1.25rem;
    max-width: 60rem;
    margin: 0 auto;
}

/* Every card is two rows of the grid above it rather than a box of its own, so
   the rows line up across the whole band: one row as tall as the longest quote,
   one for the signatures. The pictures and names therefore all start at the same
   height whatever length the quotes are, and a role that runs to three lines
   grows downwards instead of lifting its portrait.

   Bottom-aligning the signatures was the other way to make them agree, and it
   is worse: it lines up the last line of grey text, which nobody is looking at,
   by moving the faces, which everybody is. */
.quotes li {
    text-align: center;
    grid-row: span 2;
    display: grid;
    grid-template-rows: subgrid;
}

.quotes blockquote {
    margin: 0;
    font-style: italic;
    font-weight: 600;
    font-size: 1.1rem;
    color: var(--navy);
}

/* The signature: portrait, then name and role beside it, under the quote. The
   row is centred as a whole while its text is not, so the name sits against the
   picture rather than floating in the middle of the column. */
.quote-by {
    display: flex;
    /* Level with the name, not with the middle of however many lines the role
       runs to: a portrait that drifts downwards as the role gets longer stops
       looking attached to the name it belongs to. */
    align-items: flex-start;
    justify-content: center;
    gap: .75rem;
    text-align: left;
}

/* Beside the name rather than above the whole card, and big enough to be a face
   rather than a token: at 3.5rem these read as icons, which is not what a
   photograph of somebody vouching for you should look like. Its ratio is in the
   markup too, so a card does not resize when a portrait lands. */
.quotes img {
    width: 7rem;
    height: 7rem;
    flex: none;
    object-fit: cover;
    border-radius: 50%;
    display: block;
}

.quote-name { font-weight: 600; margin: 0; }
.quote-role { color: var(--muted); font-size: .9rem; margin: 0; }

/* A quote with no portrait keeps its name in the middle of the card rather than
   sitting off to one side for no visible reason. */
.quote-by:not(:has(img)) { text-align: center; }

@media (max-width: 820px) {
    .band { padding: 2.5rem 0; }
    .band h2 { font-size: 1.5rem; margin-bottom: 1.5rem; }

    .hero-band-inner,
    .split { flex-direction: column; gap: 1.5rem; }

    .hero-band-image { width: 100%; height: 13rem; }
    .split-image { height: 13rem; }

    /* The band is a column now, and align-items: center on it means every child
       is as wide as its own content instead of as wide as the band. For the
       speakers that is the difference between a grid that knows how much room
       it has and one that does not: an auto-fit grid with no width to fill
       collapses to a single column, which put one portrait per row down a page
       with space for four. Width first, flex-basis off - in a column that basis
       is a height and was never doing anything here. */
    .hero-band-inner > .speakers {
        flex: none;
        width: 100%;
    }
}
