/**
 * SRD programme - ruled paper, in the same visual world as the SRD26
 * exhibitor index.
 *
 * The design language is deliberately the one already approved for
 * /srd26/exhibitors/: entries are separated by 1px grid gaps rather than being
 * cards, no shadows, no radius, no fills, Outfit throughout, and the red is
 * spent only where it earns attention. A visitor moving between the two pages
 * should not notice a change of hand.
 *
 * Tokens are copied rather than imported. The exhibitor stylesheet is a
 * standalone file in a different plugin, and this page has to keep working if
 * that one is ever reskinned.
 *
 * Structure of the ruling: a container paints the rule colour and sets
 * gap:1px, and its children paint the paper colour, so every rule on the page
 * is a gap rather than a border. That only holds where both sides of the gap
 * are guaranteed to be filled, so a stack whose tail can be empty (sessions
 * inside one lane) uses real borders instead.
 *
 * @package SRD_Schedule
 */

.srdsch {
  /* Dark only, by design, matching the exhibitor index: the page commits to
     one visual world rather than keeping two that drift apart. */
  --srdsch-red:        #ff4a3d;
  --srdsch-paper:      #041b2f;
  --srdsch-paper-sunk: #082741;
  --srdsch-plate:      #0b3050;

  --srdsch-ink:    #eaf1f6;
  /* A cooler ink at about the lightness of --srdsch-ink. The role line in the
     speaker panel, where the weight came down to 400 and the colour carries
     the emphasis instead. Owner's value, 2026-09-10. */
  --srdsch-ink-cool: #dcefff;
  --srdsch-ink-60: #9fb3c4;
  --srdsch-ink-40: #6d8598;
  --srdsch-rule:   #16405c;

  --srdsch-font: "Outfit", system-ui, -apple-system, "Segoe UI", sans-serif;
  --srdsch-gutter: 8.5rem;
  /* The measure of a description and of the speaker lines above it. There
     used to be a second, 62ch measure for a description with the speakers in
     a column beside it; since 2026-09-11 the speakers always sit above the
     description, so nothing is ever beside it and only this one is left.

     1040px is the owner's call, set 2026-09-10. It is about 113 characters,
     past the line length that is comfortable to track back from, and on any
     viewport under roughly 1500px the row runs out first, so in practice a
     description simply fills its row. Deliberate: do not "correct" it back to
     a typographic measure. */
  --srdsch-measure-wide: 1040px;

  font-family: var(--srdsch-font);
  color: var(--srdsch-ink);
  /* NOTE: do NOT set container-type here. Inline-size containment stops the
     contents contributing to intrinsic width, and Elementor wraps widgets in a
     flex container, so the whole programme collapses to width 0. The same trap
     already bit the exhibitor grid. No @container query is used in this file. */
}

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

/* -- Neutralising the theme ------------------------------------------------
   hello-elementor/assets/css/reset.css sets, verbatim:

     a                          { color: #c36 }
     button                     { border: 1px solid #c36; color: #c36;
                                  border-radius: 3px; display: inline-block;
                                  white-space: nowrap }
     button:hover, button:focus { background-color: #c36; color: #fff }

   The first version of this file reset `a` and forgot `button`, so the
   question mark beside a speaker picked up the theme's pink fill the moment
   it was hovered or focused. Both are handled now.

   Specificity is deliberate and layered, the same scheme the exhibitor skin
   settled on:

     theme        button:hover        (0,1,1)
     this reset   .srdsch button:hover (0,2,1)  wins
     components   .srdsch .thing:hover (0,3,0)  wins over both

   which is why every component rule below is scope-prefixed. The state rules
   set background ONLY: including colour here made a merely-focused button
   fall back to `inherit`, which turned the dialog close button black against
   the dark backdrop the moment it took focus on open. */

/* BASE (0,1,1) — colour, border and wrapping. */
.srdsch a,
.srdsch button {
  color: inherit;
  border-color: currentColor;
  border-radius: 0;
  background-color: transparent;
  background-image: none;
  box-shadow: none;
  text-shadow: none;
  font-family: inherit;
  /* The theme's nowrap is what stopped long titles wrapping. */
  white-space: normal;
  -webkit-appearance: none;
  appearance: none;
}

/* STATE (0,2,1) — background only. */
.srdsch a:hover,
.srdsch a:focus,
.srdsch a:active,
.srdsch a:focus-visible,
.srdsch button:hover,
.srdsch button:focus,
.srdsch button:active,
.srdsch button:focus-visible {
  background-color: transparent;
  background-image: none;
  box-shadow: none;
  text-shadow: none;
}

.srdsch :focus-visible {
  outline: 2px solid var(--srdsch-red);
  outline-offset: 3px;
}

.srdsch ::selection { background: var(--srdsch-red); color: #fff; }

/* Links an editor puts inside a cell. Underlined, because in a dense
   programme colour alone is not a reliable signal, and the accent is reserved
   for hover so a paragraph of links does not turn into a red block. */
.srdsch .srdsch-title-link,
.srdsch .srdsch-speakers a,
.srdsch .srdsch-desc a,
.srdsch .srdsch-sd-desc a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  text-decoration-color: var(--srdsch-rule);
  transition: color .12s linear, text-decoration-color .12s linear;
}

.srdsch .srdsch-title-link:hover,
.srdsch .srdsch-speakers a:hover,
.srdsch .srdsch-desc a:hover,
.srdsch .srdsch-sd-desc a:hover {
  color: var(--srdsch-red);
  text-decoration-color: var(--srdsch-red);
}

/* -- Day switcher ---------------------------------------------------------- */

.srdsch-days {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .35rem 1.9rem;
  margin: 0 0 1.4rem;
  border-bottom: 1px solid var(--srdsch-rule);
}

.srdsch-day-btn {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--srdsch-ink-40);
  text-decoration: none;
  padding: 0 0 .55rem;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  cursor: pointer;
}

.srdsch-day-btn:hover { color: var(--srdsch-ink); }

.srdsch-day-btn.is-on {
  color: var(--srdsch-ink);
  border-bottom-color: var(--srdsch-red);
}

/* -- Days ------------------------------------------------------------------ */

.srdsch-day + .srdsch-day { margin-top: 2.6rem; }

.srdsch-day-h {
  font-size: 25px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--srdsch-ink);
  margin: 0 0 1rem;
  padding: 0;
}

/* Once the script has taken over, the active tab already names the day, so
   the heading would say it twice. It stays in the markup and stays visible
   without the script, where every day is on the page at once. */
.srdsch.srdsch-js .srdsch-day-h--tabbed {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.srdsch-day[hidden] { display: none; }

/* -- The ruled grid -------------------------------------------------------- */

.srdsch-blocks {
  display: grid;
  gap: 1px;                       /* the gap IS the rule */
  background: var(--srdsch-rule);
  border-top: 1px solid var(--srdsch-rule);
  border-bottom: 1px solid var(--srdsch-rule);
  margin: 0;
  padding: 0;
}

.srdsch-block {
  display: grid;
  grid-template-columns: var(--srdsch-gutter) minmax(0, 1fr);
  gap: 1px;
  background: var(--srdsch-rule);
}

/* -- Entrance -------------------------------------------------------------
   Rows rise into place as they reach the viewport.

   The starting state is behind .srdsch-anim, and only the script adds that
   class, and only after checking prefers-reduced-motion and that
   IntersectionObserver exists. That ordering is the whole safety argument: a
   visitor with no JavaScript, an old browser, or reduced motion never gets
   an opacity:0 rule at all, so there is no way to end up with a programme
   that is permanently invisible. The rules below are belt and braces for the
   case where motion preference changes after load. */
.srdsch-anim .srdsch-block {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition:
    opacity .5s cubic-bezier(.22, .61, .36, 1),
    transform .5s cubic-bezier(.22, .61, .36, 1);
  transition-delay: var(--srdsch-delay, 0ms);
}

.srdsch-anim .srdsch-block.is-in {
  opacity: 1;
  transform: none;
}

/* -- Time gutter ----------------------------------------------------------- */

.srdsch-time {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .1rem;
  background: var(--srdsch-paper);
  margin: 0;
  padding: 1.15rem 1rem 1.3rem 1.4rem;
  font-variant-numeric: tabular-nums;
}

.srdsch-t-from {
  font-size: 25px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.01em;
  color: var(--srdsch-ink);
}

/* The end time is secondary to the start, not incidental to it: a visitor
   deciding whether to sit through a session reads both. It was set at 13px in
   the dimmest ink on the palette, which made it furniture. Now two thirds the
   size of the start time and a step brighter, so it reads at a glance while
   the start still leads. */
.srdsch-t-to {
  display: flex;
  align-items: baseline;
  gap: .34rem;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--srdsch-ink-60);
}

.srdsch-t-to i {
  font-style: normal;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--srdsch-ink-40);
}

.srdsch-t-note {
  margin-top: .5rem;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--srdsch-red);
}

.srdsch-time--tbc {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--srdsch-ink-40);
  line-height: 1.4;
}

/* -- One session ----------------------------------------------------------- */

.srdsch-item {
  /* Held as custom properties so the image plate can cancel them exactly and
     bleed to the edges of the row. */
  --srdsch-pad-x: 1.4rem;
  --srdsch-pad-t: 1.15rem;
  --srdsch-pad-b: 1.35rem;

  background: var(--srdsch-paper);
  margin: 0;
  /* No padding on the row itself. It moved to the text block below so the
     image is flush with the rules by construction. The previous version
     bled the image out with negative margins, and Elementor ships
     `.elementor .elementor-widget:not(...):not(...) figure { margin: 0 }`
     at roughly (0,4,1), which beat them and left the image sitting politely
     inside the padding. Nothing to outrank if there is no margin to win. */
  padding: 0;
  transition: background .12s linear;

  /* A column flex box, so the inner wrapper below can be told to take the
     whole height. Without this the article stretches to match a taller
     neighbouring column while the wrapper inside it stays content-height, and
     the image band stops halfway down the row. */
  display: flex;
  flex-direction: column;
}

.srdsch-item:hover { background: var(--srdsch-paper-sunk); }

/* Sessions stacked inside one lane. A lane's tail can be empty, so these
   separators are borders rather than gaps: a gap would show the rule colour
   as a slab under the last session of a short column. */
.srdsch-item--stacked + .srdsch-item--stacked {
  border-top: 1px solid var(--srdsch-rule);
}

.srdsch-item-time {
  display: flex;
  align-items: baseline;
  gap: .34rem;
  margin: 0 0 .6rem;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .01em;
  font-variant-numeric: tabular-nums;
  color: var(--srdsch-ink);
}

.srdsch-item-time i {
  font-style: normal;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--srdsch-ink-40);
}

.srdsch-item-main {
  display: flex;
  /* stretch, not flex-start: the image is a full-height band down the side of
     the row, so it has to take the row's height rather than its own. */
  align-items: stretch;
  /* The space between image and text is the text's own left padding. */
  gap: 0;
  flex: 1 1 auto;
}

.srdsch-item-text {
  min-width: 0;
  flex: 1 1 auto;
  padding: var(--srdsch-pad-t) var(--srdsch-pad-x) var(--srdsch-pad-b);
}

/* A lone session in a column that spans hours, the exhibition or an
   afternoon-long workshop, was four lines pinned to the top of a very tall
   box. Centred, it reads as one continuous thing occupying the whole window
   instead of a note that ran out. */
.srdsch-lane > .srdsch-item:only-child .srdsch-item-text { align-self: center; }

.srdsch-kicker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem 1rem;
  margin: 0 0 .5rem;
  padding: 0;
}

.srdsch-type,
.srdsch-area {
  display: flex;
  align-items: center;
  gap: .45rem;
  font-size: 10px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--srdsch-ink-40);
}

.srdsch-area { color: var(--srdsch-ink-60); }

.srdsch-sw {
  width: 10px;
  height: 10px;
  flex: none;
  background: var(--srdsch-c, var(--srdsch-ink-40));
}

.srdsch-title {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.015em;
  color: var(--srdsch-ink);
  margin: 0;
  padding: 0;
  text-wrap: balance;
  /* Session titles are arbitrary strings; a long unbroken one must break
     rather than push the column out of the grid. */
  overflow-wrap: anywhere;
}

/* -- A title that opens the description -----------------------------------
   The script moves the title's text into this button, so it has to look
   exactly like the heading it sits in: every property inherited, nothing of
   the button left. Scope-prefixed to (0,2,0), which beats the theme's
   `button:hover, button:focus { background:#c36; color:#fff }` at (0,1,1). */
.srdsch .srdsch-title-btn {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  text-align: left;
  text-transform: none;
  cursor: pointer;
}

.srdsch .srdsch-title-btn:hover,
.srdsch .srdsch-title-btn:focus {
  color: inherit;
  background-color: transparent;
}

/* The cue. A touch screen has nothing to hover, so there it is always
   shown, red, on a line of its own under the title. */
.srdsch .srdsch-cue {
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: .04em;
  white-space: nowrap;
}

.srdsch .srdsch-cue--hover { display: none; }

.srdsch .srdsch-cue--touch {
  display: block;
  margin-top: .3rem;
  color: var(--srdsch-red);
}

/* With a pointer, the cue appears after the title, in white, only while the
   title is hovered or focused from the keyboard.

   Greedy wrapping in here, not the heading's balance. Balanced lines are
   recomputed whenever text is added, so the cue appearing would move words
   between the title's lines under the pointer, and a title that reflows can
   shrink out from under the pointer, lose the hover, drop the cue, reflow
   back and flicker. Greedy lines only ever grow at the end. */
@media (hover: hover) and (pointer: fine) {
  .srdsch .srdsch-title-btn { text-wrap: wrap; }

  .srdsch .srdsch-cue--touch { display: none; }

  .srdsch .srdsch-title-btn:hover .srdsch-cue--hover,
  .srdsch .srdsch-title-btn:focus-visible .srdsch-cue--hover {
    display: inline;
    margin-left: .6em;
    font-weight: 500;
    letter-spacing: .02em;
    color: #fff;
  }
}

.srdsch-speakers {
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.42;
  color: var(--srdsch-ink-60);
  margin: .45rem 0 0;
  padding: 0;
  max-width: var(--srdsch-measure-wide);
}

/* -- Speakers --------------------------------------------------------------
   One line per speaker, bulleted, above the description:

     * Organization, Name - Talk title

   The owner's specification of 2026-09-11, bullets included. The name is
   the brightest thing on the line because it is the control that opens the
   profile; organisation and talk sit in the quieter ink either side of it.
   Scope-prefixed so the theme's list styling cannot move the bullets. */
.srdsch .srdsch-people {
  list-style: disc outside;
  margin: .5rem 0 0;
  padding: 0 0 0 1.15em;
  max-width: var(--srdsch-measure-wide);
}

.srdsch .srdsch-person {
  margin: 0;
  padding: 0;
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--srdsch-ink-60);
}

.srdsch .srdsch-person + .srdsch-person { margin-top: .22rem; }

.srdsch-person::marker { color: var(--srdsch-ink-40); }

.srdsch-person-org { font-weight: 500; }

.srdsch-person-name {
  font-weight: 600;
  color: var(--srdsch-ink);
}

/* The name as a control: the button the script puts there when the speaker
   has a profile to open, or the link to their own page when they do not.
   Underlined in the rule colour at rest, the same signal every other link on
   the programme gives, so it reads as clickable without the red label that
   used to sit under it. */
.srdsch .srdsch-person-open,
.srdsch .srdsch-person-link {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-weight: 600;
  letter-spacing: inherit;
  text-align: left;
  color: var(--srdsch-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
  text-decoration-color: var(--srdsch-ink-40);
  cursor: pointer;
  transition: color .12s linear, text-decoration-color .12s linear;
}

.srdsch .srdsch-person-open:hover,
.srdsch .srdsch-person-open:focus-visible,
.srdsch .srdsch-person-link:hover,
.srdsch .srdsch-person-link:focus-visible {
  color: var(--srdsch-red);
  background-color: transparent;
  text-decoration-color: var(--srdsch-red);
}

/* -- Portraits -------------------------------------------------------------
   Only when portraits are switched on for the programme on the Agenda screen
   AND the list carries at least one. The portrait then stands where the
   bullet would, so the bullet goes: a dot beside a picture beside a name is
   one marker too many. Switched off, none of this markup exists at all. */
.srdsch .srdsch-people--faces {
  list-style: none;
  padding-left: 0;
}

.srdsch .srdsch-people--faces .srdsch-person {
  display: flex;
  align-items: center;
  gap: .7rem;
}

.srdsch .srdsch-people--faces .srdsch-person + .srdsch-person { margin-top: .65rem; }

.srdsch-person-text { display: block; min-width: 0; }

.srdsch-face {
  width: var(--srdsch-face-size, 70px);
  height: var(--srdsch-face-size, 70px);
  flex: none;
  overflow: hidden;
  /* Deliberately NOT a centring grid. An image larger than its box gets
     centred by place-items, which moved the offsets below off their origin
     and magnified the wrong corner of the card. The image is anchored to the
     top left and positioned from there instead. */
  position: relative;
  display: block;
  border: 1px solid var(--srdsch-rule);
  background: var(--srdsch-plate);
  /* A square, like every other plate here. A circle would be the one rounded
     thing on a page that has no radius anywhere else. */
  margin-top: .1rem;
}

/*
 * Two knobs rather than a fixed crop.
 *
 * The default is an ordinary portrait crop, biased above centre because that
 * is where a face sits in a head-and-shoulders photo.
 *
 * The zoom exists because this site's speaker photos are not portraits: they
 * are 1200x1200 composite cards with the person in a circle and their name and
 * talk title set beside it. Shrunk into a 36px square, a whole card is a grey
 * smudge. facecrop="card" on the shortcode magnifies the circle instead. Both
 * values are plain custom properties, so a different card layout can be dialled
 * in from the theme without touching this file.
 */
.srdsch .srdsch-face img {
  /* Oversize then pull back, rather than transform: scale(). Scaling about a
     transform-origin keeps that point FIXED where it already sat, it does not
     bring it to the middle, so a first attempt at this magnified the empty
     blue corner of the card instead of the face.
     The image is drawn at zoom x the plate, then offset so the focus point
     lands dead centre:  offset = 50% - focus * zoom.
     At the default zoom of 1 both offsets are 50% - 50% = 0, so an ordinary
     portrait is untouched and object-position does the work instead.
     Percentage margins resolve against the containing block WIDTH, top and
     bottom included, which is only safe because this plate is square. */
  position: absolute;
  top: 0;
  left: 0;
  width: calc(100% * var(--srdsch-face-zoom, 1));
  height: calc(100% * var(--srdsch-face-zoom, 1));
  /* WordPress and the theme both set img{max-width:100%}, which would cap the
     magnified width straight back to the plate. */
  max-width: none;
  display: block;
  object-fit: cover;
  object-position: var(--srdsch-face-pos, 50% 25%);
  margin-left: calc(50% - var(--srdsch-face-x, 50%) * var(--srdsch-face-zoom, 1));
  margin-top: calc(50% - var(--srdsch-face-y, 50%) * var(--srdsch-face-zoom, 1));
}

.srdsch-face--none {
  display: grid;
  place-items: center;
}

.srdsch-initials {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .04em;
  line-height: 1;
  color: var(--srdsch-ink-40);
}

/* Deliberately NOT stepped down inside a parallel column: most speakers sit
   in one, and shrinking it there would undo the size. */

/* -- Speaker panel and session popup --------------------------------------- */

.srdsch-dialog {
  width: min(50rem, calc(100vw - 2rem));
  max-height: min(42rem, calc(100vh - 3rem));
  padding: 0;
  border: 1px solid var(--srdsch-rule);
  border-radius: 0;
  background: var(--srdsch-paper);
  color: var(--srdsch-ink);
  font-family: var(--srdsch-font);
  overflow: auto;
}

.srdsch-dialog::backdrop {
  background: rgba(2, 12, 22, .72);
}

.srdsch-dialog-inner {
  display: flex;
  align-items: flex-start;
  gap: 1.8rem;
  padding: 1.7rem 1.8rem 1.9rem;
}

/* Portrait and links are one column. The links used to sit under the
   biography, where a long one pushed them below the fold of the panel.
   The portrait here is not affected by the Agenda screen's portrait switch,
   which governs the programme rows only. */
.srdsch-dialog .srdsch-person-aside {
  flex: none;
  width: 200px;
  max-width: 40%;
}

.srdsch-dialog .srdsch-person-photo {
  width: 100%;
  /* Square, whatever the file is, so two speakers open at the same size. */
  aspect-ratio: 1 / 1;
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--srdsch-rule);
  background: var(--srdsch-plate);
}

.srdsch-dialog .srdsch-person-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}

.srdsch-dialog .srdsch-person-body { min-width: 0; flex: 1 1 auto; }

.srdsch-dialog .srdsch-person-dname {
  margin: 0;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.015em;
  color: var(--srdsch-ink);
}

/* Weight 400, and the colour does the work the weight used to. It can afford
   to be light because the red rule below it, not its own boldness, is what
   separates it from the biography. */
.srdsch-dialog .srdsch-person-drole {
  margin: .35rem 0 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: .02em;
  color: var(--srdsch-ink-cool);
}

/* The one red hairline in the panel, and the only place the accent is used
   here, which is why it can be this thin and still register. */
.srdsch-dialog .srdsch-person-bio {
  margin: .4rem 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--srdsch-red);
  font-size: 14px;
  line-height: 1.6;
  color: var(--srdsch-ink-60);
}

.srdsch-dialog .srdsch-person-bio p { margin: 0 0 .6em; }
.srdsch-dialog .srdsch-person-bio p:last-child { margin-bottom: 0; }

/* A list under the portrait, one link per line. */
.srdsch-dialog .srdsch-person-links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin: .9rem 0 0;
  padding: 0;
}

.srdsch-dialog .srdsch-person-links li { min-width: 0; }

.srdsch-dialog .srdsch-person-links a {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--srdsch-ink);
  text-decoration: none;
  border-bottom: 2px solid var(--srdsch-rule);
  padding-bottom: .1rem;
}

.srdsch-dialog .srdsch-person-links a:hover {
  color: var(--srdsch-red);
  border-bottom-color: var(--srdsch-red);
}

.srdsch .srdsch-dialog-close {
  position: absolute;
  top: .55rem;
  right: .55rem;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--srdsch-rule);
  background: var(--srdsch-paper);
  color: var(--srdsch-ink-60);
  font-family: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.srdsch .srdsch-dialog-close:hover,
.srdsch .srdsch-dialog-close:focus-visible {
  color: var(--srdsch-red);
  border-color: var(--srdsch-red);
  background-color: var(--srdsch-paper);
}

@media (max-width: 34rem) {
  .srdsch-dialog-inner { flex-direction: column; gap: 1.1rem; }
  .srdsch-dialog .srdsch-person-aside { width: 160px; max-width: 100%; }
  /* Side by side again once the column has stacked, so a phone does not open
     on a picture with the name pushed off the bottom of the panel. */
  .srdsch-dialog .srdsch-person-links { flex-direction: row; flex-wrap: wrap; gap: .4rem .9rem; }
}

/* The session popup is text only, so it is narrower than the profile panel,
   which has a portrait column to hold, and it is one column at every width.

   Its composition copies the profile panel on purpose: title at the panel
   name's size, the time in the panel role's light ink, and the one red rule
   over the body. The two open from the same programme and should read as one
   family. */
.srdsch-dialog.srdsch-dialog--session { width: min(44rem, calc(100vw - 2rem)); }

.srdsch-dialog .srdsch-dialog-inner--session { display: block; }

.srdsch-dialog .srdsch-sd .srdsch-kicker {
  margin: 0 0 .55rem;
  /* Clear of the close button in the corner. */
  padding-right: 2.2rem;
}

.srdsch-dialog .srdsch-sd--keynote .srdsch-type { color: var(--srdsch-red); }

.srdsch-dialog .srdsch-sd-title {
  margin: 0;
  padding-right: 2.2rem;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.015em;
  color: var(--srdsch-ink);
  overflow-wrap: anywhere;
}

.srdsch-dialog .srdsch-sd-when {
  margin: .35rem 0 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  color: var(--srdsch-ink-cool);
}

.srdsch-dialog .srdsch-sd-desc {
  margin: .4rem 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--srdsch-red);
  font-size: 14px;
  line-height: 1.6;
  color: var(--srdsch-ink-60);
}

.srdsch-dialog .srdsch-sd-desc p { margin: 0 0 .6em; }
.srdsch-dialog .srdsch-sd-desc > :last-child { margin-bottom: 0; }

/* Editors write bulleted lists into descriptions. Indented enough to keep
   the bullets inside the panel, and no more. */
.srdsch-dialog .srdsch-sd-desc ul,
.srdsch-dialog .srdsch-sd-desc ol {
  margin: 0 0 .6em;
  padding-left: 1.2em;
}

.srdsch-dialog .srdsch-sd-desc li + li { margin-top: .15em; }

/* Set like the links under a speaker's portrait, so a link out of either
   popup looks the same. */
.srdsch-dialog .srdsch-sd-desc .srdsch-desc-more { margin: 1rem 0 0; }

.srdsch .srdsch-dialog .srdsch-desc-more a {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--srdsch-ink);
  text-decoration: none;
  border-bottom: 2px solid var(--srdsch-rule);
  padding-bottom: .1rem;
}

.srdsch .srdsch-dialog .srdsch-desc-more a:hover {
  color: var(--srdsch-red);
  border-bottom-color: var(--srdsch-red);
}

/* Under the speakers, never beside them (2026-09-11). The side-by-side pair
   that used to wrap itself on a flex-basis floor is gone with the wrapper
   that held it; a slot is now kicker, title, speakers, description, top to
   bottom, in every column width. */
.srdsch-desc {
  font-size: 14px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--srdsch-ink-60);
  margin: .6rem 0 0;
  max-width: var(--srdsch-measure-wide);
}

.srdsch-desc p { margin: 0 0 .5em; }
.srdsch-desc p:last-child { margin-bottom: 0; }

/* The slot's own link, when its description opens in the popup and the
   title can no longer be the link. (0,2,0), because `.srdsch-desc p` at
   (0,1,1) would otherwise take its top margin away. */
.srdsch .srdsch-desc-more { margin: .7em 0 0; }

/* -- Image plate ----------------------------------------------------------- */

/*
 * The image is a band down the leading edge of the row, not a stamp floating
 * inside it. It cancels the row padding with negative margins so it meets the
 * rules above, below and to the left, and stretches to whatever height the
 * text beside it needs. At 84px inset it read as an afterthought.
 */
.srdsch .srdsch-plate {
  width: var(--srdsch-plate-w, 168px);
  flex: none;
  align-self: stretch;
  min-height: var(--srdsch-plate-min, 104px);
  margin: 0;
  padding: 0;
  background: var(--srdsch-plate);
  border: 0;
  border-right: 1px solid var(--srdsch-rule);
  overflow: hidden;
  /* Positioned, not a centring grid: the image below is placed against this
     box rather than sized by height, which is the only way to be sure it
     fills. */
  position: relative;
}

/*
 * inset, not width/height. Elementor ships `.elementor img { height: auto }`,
 * which is (0,1,1), exactly the same specificity as `.srdsch-plate img`, and
 * its stylesheet loads after this one, so it won the tie and the image sized
 * itself to its own aspect ratio: 99px tall inside a 241px band. An absolutely
 * placed box with all four offsets at 0 fills its container whatever `height`
 * is set to, so there is no tie left to lose.
 */
.srdsch .srdsch-plate img {
  display: block;
  position: absolute;
  inset: 0;
  /* Both dimensions stated. Dropping them let WordPress's own width="1919"
     height="1280" attributes through as presentational hints, and the image
     rendered at full natural size behind overflow:hidden. At (0,2,1) these
     also outrank `.elementor img { height: auto }`, which is the rule that
     beat the previous attempt. */
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
}

/* A photograph is cropped to the band without apology; a logo or a diagram is
   letterboxed, because cropping one destroys it. */
.srdsch .srdsch-plate--cover img { object-fit: cover; object-position: center center; }

.srdsch .srdsch-plate--contain {
  padding: .7rem;
  background: #f2f5f7;
}

.srdsch .srdsch-plate--contain img { object-fit: contain; }

/* -- Parallel tracks ------------------------------------------------------- */

/* The body of a parallel block: anything that runs across the whole window
   stacked above the columns that only run in one room. */
.srdsch-pbody {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--srdsch-rule);
  min-width: 0;
}

.srdsch-loose {
  background: var(--srdsch-paper);
  display: flex;
  flex-direction: column;
}

.srdsch-loose .srdsch-item + .srdsch-item {
  border-top: 1px solid var(--srdsch-rule);
}

/* A loose session is full width, so it takes the full-width image band and
   title size rather than the narrow ones a column gets. */
.srdsch .srdsch-loose .srdsch-item--stacked .srdsch-plate {
  width: var(--srdsch-plate-w, 168px);
  min-height: var(--srdsch-plate-min, 104px);
}

.srdsch-loose .srdsch-item--stacked .srdsch-title { font-size: 20px; }

/* Flexbox rather than grid columns on purpose: a track spanning two lanes
   needs a proportional width, and flex-grow takes a custom property without
   the repeat(var(--n)) substitution that grid would need. */
.srdsch-tracks {
  display: flex;
  align-items: stretch;
  gap: 1px;
  background: var(--srdsch-rule);
  min-width: 0;
  flex: 1 1 auto;
}

.srdsch-track {
  display: flex;
  flex-direction: column;
  flex-grow: var(--srdsch-span, 1);
  flex-shrink: 1;
  flex-basis: 0;
  min-width: 0;
  background: var(--srdsch-paper);
}

.srdsch-track-h {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: 0;
  padding: .85rem 1.4rem .7rem;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--srdsch-ink);
  border-bottom: 1px solid var(--srdsch-rule);
}

/* An unnamed column still needs the header's height, or its session's title
   sits a line higher than the titles beside it. */
.srdsch-track-h--none::after {
  content: "";
  display: block;
  min-height: 1.3em;
}

.srdsch-lanes {
  display: flex;
  align-items: stretch;
  gap: 1px;
  background: var(--srdsch-rule);
  flex: 1 1 auto;
  min-width: 0;
}

.srdsch-lane {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
  background: var(--srdsch-paper);
}

/* The last session in a column takes the height left over, so a slot that
   runs long, the exhibition or a workshop spanning the afternoon, reads as
   one continuous block down to the foot of its neighbours rather than a card
   with dead space under it. */
.srdsch-lane > .srdsch-item:last-child { flex: 1 1 auto; }

/* Same shape in a parallel column as in a full-width row: the image is a band
   down the leading edge, not a banner over the top. It narrows instead, with
   clamp so a two-column block gets a generous band and a four-column one still
   leaves the text somewhere to live. */
.srdsch-item--stacked .srdsch-item-main {
  flex-direction: row;
  gap: 1rem;
}

.srdsch .srdsch-item--stacked .srdsch-plate {
  width: clamp(78px, 34%, 150px);
  min-height: 88px;
}

.srdsch-item--stacked .srdsch-title { font-size: 17.5px; }

/* The clock moved inside the text column so the band can run the full height,
   so it needs the spacing a leading line wants rather than the block's. */
.srdsch-item--stacked .srdsch-item-time { margin-bottom: .35rem; }

/* -- Session types --------------------------------------------------------- */

/* A keynote is the one type that gets the accent. Everything else is
   differentiated by weight and quietness, so the page keeps one focal colour. */
.srdsch-item--keynote .srdsch-type { color: var(--srdsch-red); }

/* Breaks, expo hours and the apero are structure rather than programme: they
   hold the reader's place in the day without competing with the sessions. */
.srdsch-item.is-quiet {
  --srdsch-pad-t: .85rem;
  --srdsch-pad-b: .9rem;
  --srdsch-plate-min: 72px;

  background: var(--srdsch-paper-sunk);
}

.srdsch-item.is-quiet:hover { background: var(--srdsch-paper-sunk); }

.srdsch-item.is-quiet .srdsch-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--srdsch-ink-60);
}

.srdsch-item.is-quiet .srdsch-kicker { margin-bottom: .3rem; }

/* -- Empty and configuration states --------------------------------------- */

.srdsch--empty { padding: 1.6rem 0; }

.srdsch-empty,
.srdsch-notice {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--srdsch-ink-60);
}

.srdsch-notice {
  border-left: 2px solid var(--srdsch-red);
  padding-left: .9rem;
  color: var(--srdsch-ink);
}

/* -- Narrow screens -------------------------------------------------------- */

/* The time-beside-session layout needs roughly 34rem before the session
   column gets too narrow to read; below that the time becomes a band above
   its session, and parallel areas stack instead of sitting side by side. */
@media (max-width: 47.99rem) {
  .srdsch-block { grid-template-columns: minmax(0, 1fr); }

  .srdsch-time {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .1rem .7rem;
    padding: .85rem 1.1rem .85rem;
  }

  .srdsch-t-from { font-size: 19px; }
  .srdsch-t-to { font-size: 14.5px; }
  .srdsch-t-note { margin-top: 0; margin-left: auto; }

  .srdsch-tracks,
  .srdsch-lanes { flex-direction: column; }

  .srdsch-track,
  .srdsch-lane { flex-basis: auto; }

  .srdsch-item {
    --srdsch-pad-x: 1.1rem;
    --srdsch-pad-t: 1rem;
    --srdsch-pad-b: 1.15rem;
    --srdsch-plate-w: 104px;
    --srdsch-plate-min: 88px;
  }

  /* Width is no longer scarce once a track is full-bleed, so the image goes
     back beside the text and the title back to full size. */
  .srdsch-item--stacked .srdsch-item-main {
    flex-direction: row;
    gap: 1.2rem;
  }

  .srdsch-item--stacked .srdsch-plate {
    width: var(--srdsch-plate-w, 104px);
    min-height: var(--srdsch-plate-min, 88px);
  }

  .srdsch-item--stacked .srdsch-title { font-size: 18px; }

  .srdsch-title { font-size: 18px; }
  .srdsch-day-h { font-size: 21px; }

  .srdsch-days {
    gap: .35rem 1.3rem;
    /* A four-day programme would otherwise wrap the tabs into a block that
       pushes the whole programme down the phone screen. */
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .srdsch-days::-webkit-scrollbar { display: none; }
  .srdsch-day-btn { flex: none; }
}

@media (prefers-reduced-motion: reduce) {
  .srdsch * { transition: none !important; }

  /* Killing the transition alone would freeze every row at opacity 0, which
     is how a reduced-motion setting turns into a blank page. */
  .srdsch-anim .srdsch-block {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* -- Print ----------------------------------------------------------------- */

/* People print a programme and carry it around the venue, so it inverts to
   ink on paper, drops the images, and shows every day rather than whichever
   tab happened to be open. */
@media print {
  .srdsch {
    --srdsch-paper:      #fff;
    --srdsch-paper-sunk: #f2f2f2;
    --srdsch-ink:        #000;
    --srdsch-ink-60:     #333;
    --srdsch-ink-40:     #555;
    --srdsch-rule:       #999;
    --srdsch-red:        #000;
    color: #000;
  }

  .srdsch-days { display: none; }
  .srdsch-day[hidden] { display: block !important; }
  .srdsch.srdsch-js .srdsch-day-h--tabbed {
    position: static;
    width: auto;
    height: auto;
    clip-path: none;
  }

  .srdsch-plate { display: none; }
  .srdsch-block { break-inside: avoid; }
  .srdsch-item { break-inside: avoid; }

  /* Paper cannot open a popup, so a description held back for one prints
     where it would have been, and the cue that says "click" does not. */
  .srdsch .srdsch-desc--pop[hidden] { display: block; }
  .srdsch .srdsch-cue { display: none; }

  /* A row that had not scrolled into view yet must still print. */
  .srdsch-anim .srdsch-block {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* -- Preview banner --------------------------------------------------------
   Only ever rendered for a logged-in editor following a nonced preview link,
   so it is never on the public page. */

/*
 * Literal colours, not the tokens. This banner is prepended BEFORE the
 * programme wrapper, so it sits outside .srdsch where every --srdsch-* custom
 * property is defined. Referencing them here resolved to nothing and the text
 * inherited the theme's dark body colour: near-black on navy, unreadable.
 */
.srdsch-preview {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .3rem .8rem;
  margin: 0 0 1.2rem;
  padding: .8rem 1.1rem;
  background: #082741;
  border-left: 3px solid #ff4a3d;
  font-family: "Outfit", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 13.5px;
  line-height: 1.5;
  color: #cfdce6;
}

.srdsch-preview strong {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #ff4a3d;
}

.srdsch-preview span { color: #cfdce6; }

.srdsch-preview a {
  color: #fff;
  text-decoration: underline;
  text-decoration-color: #4a7595;
  text-underline-offset: .18em;
}

.srdsch-preview a:hover { color: #ff4a3d; text-decoration-color: #ff4a3d; }
