/* PyLadiesCon portal brand styling.
   Palette + fonts taken from conference.pyladies.com (pyladies/global-conference
   theme.json + base.css): raspberry #ee264d, navy #152035, Blinker + Orbitron. */

:root {
    --pyl-primary: #ee264d;
    --pyl-primary-dark: #c01f3f;
    --pyl-navy: #152035;

    --bs-primary: #ee264d;
    --bs-primary-rgb: 238, 38, 77;
    --bs-primary-text-emphasis: #c01f3f;
    --bs-dark: #152035;
    --bs-dark-rgb: 21, 32, 53;
    --bs-link-color: #ee264d;
    --bs-link-color-rgb: 238, 38, 77;
    --bs-link-hover-color: #c01f3f;
    --bs-link-hover-color-rgb: 192, 31, 63;
}

body {
    font-family: "Blinker", system-ui, sans-serif;
}

/* Display headings, the brand wordmark, and the active-conference badge use the
   conference's geometric display face. */
.navbar-brand,
.display-1,
.display-2,
.display-3,
.display-4,
.display-5,
.display-6 {
    font-family: "Orbitron", system-ui, sans-serif;
    letter-spacing: 0.01em;
}

.btn-primary {
    --bs-btn-bg: #ee264d;
    --bs-btn-border-color: #ee264d;
    --bs-btn-hover-bg: #d11f42;
    --bs-btn-hover-border-color: #d11f42;
    --bs-btn-active-bg: #c01f3f;
    --bs-btn-active-border-color: #c01f3f;
    --bs-btn-disabled-bg: #ee264d;
    --bs-btn-disabled-border-color: #ee264d;
}

.btn-outline-primary {
    --bs-btn-color: #ee264d;
    --bs-btn-border-color: #ee264d;
    --bs-btn-hover-bg: #ee264d;
    --bs-btn-hover-border-color: #ee264d;
    --bs-btn-active-bg: #ee264d;
    --bs-btn-active-border-color: #ee264d;
}

.text-primary {
    color: #ee264d !important;
}

.bg-primary {
    background-color: #ee264d !important;
}

/* The colorful logo needs a light chip to read on the navy navbar. */
.navbar-logo {
    background: #fff;
    padding: 3px;
}

/* django-bootstrap5 tags required fields with the configured
   `required_css_class` ("required") on the field wrapper. Surface that as a
   visible asterisk on the label so it is clear which fields are mandatory. */
.required > .form-label::after {
    content: " *";
    color: var(--bs-danger);
}

/* Contextual left rail (portal/base_sidebar.html): pinned alongside content on
   desktop, an off-canvas drawer on mobile (handled by Bootstrap offcanvas-md). */
@media (min-width: 768px) {
    .app-sidebar {
        position: sticky;
        top: 1rem;
    }
}

/* Bootstrap compiles the active pill colour to a literal blue, so overriding
   --bs-primary alone never reaches it. Point the rail's active item at the
   brand colour instead. */
.app-sidebar .nav-pills {
    --bs-nav-pills-link-active-bg: var(--bs-primary);
}

/* Flex items default to min-width:auto, so a wide table would stretch the
   content column past its grid share and make pages with wide vs narrow
   content render at different widths. Let the column shrink to its share; wide
   tables scroll inside it (wrap them in .table-responsive). */
.app-content {
    min-width: 0;
}

/* Footer resource group headings (portal/_footer_resources.html). */
.footer-heading {
    letter-spacing: 0.04em;
}

/* Speaker checklists (templates/speakers/_checklist_item.html): items the
   portal ticks by itself are dashed so a speaker knows not to tick them. */
.checklist-item-auto {
    border-left: 3px dashed var(--bs-secondary);
}
.checklist-item-manual {
    border-left: 3px solid var(--bs-primary);
}
.checklist-item-done {
    opacity: 0.75;
}
/* Ticking an item redirects back to #item-<pk>; keep it clear of the top. */
.checklist-row {
    scroll-margin-top: 1rem;
}
/* One box size for every row, whether it is a button, a static status, or
   an automatic item: empty while open, ticked once done. */
.checklist-box {
    flex: 0 0 auto;
    width: 1.5rem;
    height: 1.5rem;
    margin-top: 0.1rem;
    padding: 0;
    border: 2px solid var(--bs-secondary);
    border-radius: 0.3rem;
    background: var(--bs-body-bg);
    color: var(--bs-body-bg);
    font-size: 0.85rem;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
button.checklist-box:hover,
button.checklist-box:focus-visible {
    border-color: var(--bs-primary);
    color: var(--bs-primary);
}
.checklist-box-static {
    border-style: dashed;
    color: var(--bs-secondary);
}
.checklist-box-done,
button.checklist-box-done:hover {
    border-color: var(--bs-success);
    border-style: solid;
    background: var(--bs-success);
    color: #fff;
}
.checklist-box-blocked {
    border-color: var(--bs-danger);
    border-style: solid;
    color: var(--bs-danger);
}
.checklist-box-skipped {
    border-color: var(--bs-secondary);
    color: var(--bs-secondary);
}
/* Waiting: nothing to click yet, and the row says why. */
.checklist-box-waiting {
    border-style: dotted;
    border-color: var(--bs-secondary);
    color: var(--bs-secondary);
    opacity: 0.75;
}
.checklist-row-waiting .checklist-title-waiting {
    color: var(--bs-secondary) !important;
}
.checklist-title-done {
    text-decoration: line-through !important;
    color: var(--bs-secondary) !important;
}
/* Due dates, right-aligned, louder the closer they are. */
.checklist-due {
    /* Bootstrap badges are 0.75em; a deadline deserves body size. */
    font-size: 0.95rem;
    font-weight: 600;
    padding: 0.4em 0.65em;
    white-space: nowrap;
}
.checklist-due-overdue {
    background: var(--bs-danger);
    color: #fff;
}
.checklist-due-soon {
    background: var(--bs-warning);
    color: var(--bs-dark);
}
.checklist-due-later {
    background: var(--bs-primary-bg-subtle);
    color: var(--bs-primary-text-emphasis);
}
.checklist-due-quiet {
    background: transparent;
    border: 1px solid var(--bs-border-color);
    color: var(--bs-secondary);
    font-weight: 400;
}

/* Flash messages as toasts (templates/portal/_toast_messages.html): shown for
   a few seconds, then fade out without JavaScript. */
.portal-toast {
    animation: portal-toast-fade 7s ease-in forwards;
}
@keyframes portal-toast-fade {
    0%, 80% { opacity: 1; }
    100% { opacity: 0; visibility: hidden; }
}

/* Checklist board cells (templates/speakers/checklist_board.html). */
.checklist-board td.cell-done { background: var(--bs-success-bg-subtle); }
.checklist-board td.cell-todo { background: var(--bs-light); }
.checklist-board td.cell-overdue { background: var(--bs-warning-bg-subtle); }
.checklist-board td.cell-blocked { background: var(--bs-danger-bg-subtle); }
.checklist-board td.cell-skipped { background: var(--bs-secondary-bg-subtle); }
.checklist-board td.cell-none { color: var(--bs-secondary); }
.checklist-board th.board-col {
    min-width: 6rem;
    max-width: 8rem;
    white-space: normal;
    vertical-align: bottom;
    line-height: 1.15;
}

/* Template editor (templates/speakers/template_detail.html): the reorder column. */
.col-order {
    width: 5rem;
}

/* Invitation email preview: the sender's own words, set apart from the template. */
.invitation-preview-note {
    background: #fff3cd;
    border-left: 3px solid #ffc107;
    padding: 0.25rem 0.75rem;
}
.invitation-preview-note > :last-child {
    margin-bottom: 0;
}
/* Task stats legend (templates/speakers/_task_stats_cards.html): the "open"
   swatch matches the empty part of the stacked bar. */
.task-legend-open {
    color: var(--bs-secondary-bg);
}

/* Login page (templates/account/login.html): the "or" between the password
   form and the sign-in code. A rule with the word in the middle on narrow
   screens; a vertical rule between the two columns from md up. */
.login-or {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    color: var(--bs-secondary);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.login-or::before,
.login-or::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--bs-border-color);
}
@media (min-width: 768px) {
    /* The column stretches to the row (align-items-stretch on the parent),
       so the rule is as tall as the taller of the two forms rather than a
       fixed height that could overhang a short one. */
    .login-or {
        flex-direction: column;
        width: auto;
        height: 100%;
        padding: 0 0.5rem;
    }
    .login-or::before,
    .login-or::after {
        border-top: 0;
        border-left: 1px solid var(--bs-border-color);
        width: 0;
    }
}

/* Accordion headers (the propose form's two sections). Bootstrap tints an
   open header and leaves a collapsed one plain white, which stops it
   reading as a header at all: the closed section looked like a stray line
   of text. A collapsed header keeps a tinted background, a border and its
   chevron, so it still looks like something to open. */
.accordion-button {
    font-weight: 600;
}
.accordion-button.collapsed {
    background-color: var(--bs-tertiary-bg);
    color: var(--bs-body-color);
}
.accordion-button.collapsed:hover {
    background-color: var(--bs-secondary-bg);
}
.accordion-button:focus {
    box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
}


/* Upload panel (templates/speakers/_upload_panel.html) and the video
   length bar on the performer's session page: tall enough to read the
   percentage inside. */
.upload-progress {
    height: 1.25rem;
}

/* At-a-glance strip on the session pages (templates/speakers/session_detail.html,
   speaker_session_detail.html): one tile per thing that needs a person,
   each a link to its section. The left edge carries the state. */
.glance-tile {
    color: inherit;
    text-decoration: none;
    border-left: 4px solid var(--bs-border-color);
}
.glance-tile:hover {
    border-color: var(--bs-primary);
    color: inherit;
}
.glance-tile.glance-ok {
    border-left-color: var(--bs-success);
}
.glance-tile.glance-warn {
    border-left-color: var(--bs-warning);
}
.glance-tile.glance-bad {
    border-left-color: var(--bs-danger);
}
.glance-label {
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--bs-secondary);
}
.glance-value {
    font-weight: 600;
}
.glance-detail {
    font-size: 0.8rem;
    color: var(--bs-secondary);
}
/* A folded card (Activity): the header is the summary. */
details.card > summary.card-header {
    cursor: pointer;
    list-style: none;
}
details.card > summary.card-header::before {
    content: "\25B8";
    display: inline-block;
    width: 1em;
}
details.card[open] > summary.card-header::before {
    content: "\25BE";
}

/* Preview fold on file rows (templates/speakers/_media_preview.html): the
   file at a readable size, never wider than the row. The width and height
   attributes on the image are hints for layout; the real size is the file's. */
.media-preview-image,
.media-preview-video {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 24rem;
}

/* The files table (templates/speakers/_media_files.html): the "More" row
   under a file carries its forms and preview on a quiet background. While
   it is open, it and the file row above it read as one block: the same
   background on both, an accent down their left edge, and a firmer rule
   under the pair, so the panel is not mistaken for another file. */
.media-table .media-group-more > td {
    border-top: 0;
    padding: 1rem 1.25rem 1.25rem;
}
.media-table .media-group:has(> .media-group-more.show) > tr > td {
    --bs-table-bg: var(--bs-tertiary-bg);
}
.media-table .media-group:has(> .media-group-more.show) > tr > td:first-child {
    border-left: 3px solid var(--bs-primary);
}
.media-table .media-group:has(> .media-group-more.show) > .media-group-more > td {
    border-bottom: 2px solid var(--bs-secondary-border-subtle);
}

/* The session picker on the export page (templates/speakers/media_export.html):
   a scrollable list with the type headings inside it. */
.session-picker-list {
    max-height: 18rem;
    overflow-y: auto;
}
.session-picker:disabled {
    opacity: 0.5;
}

/* Thumbnails on file rows, the speaker's files and the board
   (templates/speakers/_media_thumb.html). */
.media-thumb {
    object-fit: cover;
    flex: none;
}
.media-thumb-icon {
    display: inline-flex;
    width: 64px;
    height: 36px;
    align-items: center;
    justify-content: center;
    background: var(--bs-tertiary-bg);
    border-radius: 0.25rem;
    flex: none;
}

/* A transcript or another text file shown in its preview fold. */
.media-preview-text {
    height: 20rem;
}

/* The schedule editor's grid (speakers, task 4.2): the hour gutter, the
   all-channels lane, one column per channel, 5-minute rows. Cards carry
   their grid position inline, computed in speakers/schedule.py. */
.schedule-scroll {
    /* Full height on purpose: the page scrolls a long day, not a box
       within it (the rooms still scroll horizontally when they must,
       and Compact or Fit put the whole day on one screen). */
    overflow-x: auto;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
}
.schedule-grid {
    display: grid;
    grid-template-columns: 4.5rem 7rem repeat(var(--schedule-columns, 0), minmax(12rem, 1fr));
    /* Row 1 is the room headers: content-sized whatever the density,
       so Compact and Fit shrink the time rows, never the heading. A
       row is five minutes; three of them are the quarter hour that one
       row used to be, so a day is as tall as it was. */
    grid-template-rows: auto;
    grid-auto-rows: var(--schedule-row-height, 0.5rem);
    position: relative;
}
.schedule-head {
    grid-row: 1;
    position: sticky;
    top: 0;
    z-index: 3;
    background: var(--bs-body-bg);
    border-bottom: 1px solid var(--bs-border-color);
    font-weight: 600;
    font-size: 0.85rem;
    padding: 0.25rem 0.5rem;
    white-space: nowrap;
}
.schedule-hour {
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
    border-top: 1px solid var(--bs-border-color-translucent);
    padding: 0 0.25rem;
}
.schedule-cell {
    border-left: 1px solid var(--bs-border-color-translucent);
}
.schedule-cell-hour {
    border-top: 1px solid var(--bs-border-color-translucent);
}
/* The quarter hours, fainter than the hour, so a 5-minute grid still
   reads in the steps people schedule in. */
.schedule-cell-quarter {
    border-top: 1px dotted var(--bs-border-color-translucent);
}
.schedule-cell.schedule-drop {
    background: var(--bs-primary-bg-subtle);
}
.schedule-card {
    position: relative;
    z-index: 2;
    margin: 1px;
    padding: 0.1rem 0.4rem;
    overflow: hidden;
    font-size: 0.8rem;
    line-height: 1.25;
    /* Calendar blue, not the brand red: a placed session is an event,
       not an alert (Bootstrap's blue-100/200). */
    background: #cfe2ff;
    border: 1px solid #9ec5fe;
    border-radius: 0.35rem;
    cursor: grab;
}
/* A card is as tall as its slot, so the title may wrap and use that
   height; the card's own overflow clips whatever still does not fit.
   Only a card under half an hour keeps the single clipped line. */
.schedule-card-title {
    display: block;
    overflow-wrap: anywhere;
}
.schedule-card-tight .schedule-card-title {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.schedule-card-edit,
.schedule-card .text-warning-emphasis[role="img"] {
    padding: 0 0.3rem;
    font-size: 0.7rem;
    line-height: 1.3;
}
/* A card under half an hour has one line: title only, with the full
   text and times in the tooltip. */
.schedule-card-tight {
    padding-top: 0;
    padding-bottom: 0;
}
.schedule-card-tight .schedule-card-meta,
.schedule-card-tight .schedule-card-warnings {
    display: none;
}
/* Under a quarter hour (a chapter video, a lightning talk) a card is
   a sliver of its 5-minute rows: smaller lettering, no padding, the
   pencil hidden. Hovered, focused, or with its pencil form open, it
   opens to its content above its neighbours, so the title can be read
   and the pencil reached; the rows never grow, so nothing else moves.
   No top or bottom border: an 8px row has no pixel to spare for them,
   and the bottom margin is the gap between two back to back. */
.schedule-card-short {
    padding: 0 0.3rem;
    margin: 0 1px 1px;
    border-top-width: 0;
    border-bottom-width: 0;
    border-radius: 0.2rem;
    font-size: 7px;
    line-height: 7px;
}
.schedule-card-short .schedule-card-title {
    font-weight: 600;
}
.schedule-card-short .schedule-card-edit,
.schedule-card-short .text-warning-emphasis[role="img"] {
    visibility: hidden;
}
.schedule-card-short:hover,
.schedule-card-short:focus-within,
.schedule-card-short.schedule-card-open {
    align-self: start;
    min-height: 100%;
    padding: 0.1rem 0.3rem;
    border-top-width: 1px;
    border-bottom-width: 1px;
    overflow: visible;
    z-index: 15;
    font-size: 0.75rem;
    line-height: 1.25;
    box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.15);
}
/* Open, a short card sharing its row takes the whole lane, so its
   title and pencil have the room. */
.schedule-card-short.schedule-card-split:is(:hover, :focus-within, .schedule-card-open) {
    justify-self: stretch;
    width: auto;
    margin-left: 1px;
}
.schedule-card-short:hover .schedule-card-edit,
.schedule-card-short:focus-within .schedule-card-edit,
.schedule-card-short.schedule-card-open .schedule-card-edit,
.schedule-card-short:hover .text-warning-emphasis[role="img"],
.schedule-card-short:focus-within .text-warning-emphasis[role="img"],
.schedule-card-short.schedule-card-open .text-warning-emphasis[role="img"] {
    visibility: visible;
}
.schedule-band {
    /* Lavender, not grey: a band is the program's own furniture (the
       opening, a break), and grey read as disabled (purple-100/200). */
    background: #e2d9f3;
    border-color: #c5b3e6;
}
.schedule-warned {
    border-color: var(--bs-warning-border-subtle, #ffe69c);
}
/* Cards drawn on one row (a slot under 5 minutes, then the next card
   in the room) share the lane in parts, earliest on the left, so none
   covers another. An open short card takes the full lane again, above. */
.schedule-card-split {
    justify-self: start;
    width: calc(100% / var(--parts) - 2px);
    margin-left: calc(100% * var(--part) / var(--parts) + 1px);
}
/* A closed short strip has no room for the warning icon, and the
   warning that matters most there (two cards drawn in one row) is easy
   to miss, so the strip itself turns warning yellow (yellow-100). */
.schedule-card-short.schedule-warned {
    background-color: #fff3cd;
}
.schedule-card-title {
    color: inherit;
    text-decoration: none;
}
.schedule-card-title:hover {
    text-decoration: underline;
}
/* The popover hangs off the pencil itself, so it opens where the
   organizer clicked; anchored to the card, a band's popover sat at the
   card's far right edge, off screen once the grid scrolls. */
.schedule-card-menu {
    position: relative;
}
.schedule-card-menu > summary {
    list-style: none;
}
/* Only a card's pencil is squeezed: the toolbar's menus (Confirm
   schedule, Unschedule all) keep a normal button's size. */
.schedule-card-menu > summary.schedule-card-edit {
    padding: 0 0.3rem;
    line-height: 1.2;
}
.schedule-card-popover {
    position: absolute;
    top: calc(100% + 0.25rem);
    right: 0;
    z-index: 5;
    width: 14rem;
}
/* A band's pencil sits at the grid's left edge, where a right-aligned
   popover would poke into space the scroller cannot reach; it opens
   rightward instead. */
.schedule-band .schedule-card-popover {
    right: auto;
    left: 0;
}
.schedule-resize {
    position: absolute;
    inset: auto 0 0 0;
    height: 0.45rem;
    cursor: ns-resize;
}
/* An open short card is about 22px tall, and a 0.45rem handle took a
   third of it: most grabs resized the card instead of moving it. The
   handle hangs off the bottom edge instead (the open card overflows
   visibly, above its neighbours), so none of the body resizes. */
.schedule-card-short .schedule-resize {
    bottom: -7px;
    height: 8px;
}
.schedule-pending {
    cursor: grab;
}
.schedule-pending .schedule-card-popover {
    width: 13rem;
}
/* The unscheduled list grows with the page on purpose: its own
   scrollbar would clip the place flyouts, which cannot escape an
   overflow container. */
/* text-warning-emphasis is a Bootstrap 5.3 utility; this portal runs
   5.2, so the warning colour is set here with the same 5.3 value. */
.schedule-card-warnings,
.schedule-card .text-warning-emphasis {
    color: var(--bs-warning-text-emphasis, #997404);
}
.schedule-card-warnings {
    line-height: 1.2;
}

/* A grid item's minimum size is its content unless told otherwise, so a
   long title would push a card past its column; the meta line clips the
   same way the title does. */
.schedule-card {
    min-width: 0;
}
.schedule-card-body {
    flex: 1 1 auto;
    min-width: 0;
}
.schedule-card-meta {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* The click-to-add panel, floated at the clicked cell. */
.schedule-cell-panel {
    position: fixed;
    z-index: 40;
    width: 17.5rem;
}
.schedule-cell-options {
    max-height: 14rem;
    overflow: auto;
}
.schedule-cell {
    cursor: pointer;
}

/* While a card's popover is open, the card stops clipping (the popover
   would otherwise be cut to the card's height) and rises above its
   neighbours; schedule-editor.js toggles the class with the menu. */
.schedule-card.schedule-card-open {
    overflow: visible;
    z-index: 20;
}
.schedule-pending.schedule-card-open {
    position: relative;
    z-index: 20;
}

/* On a full-width band the title block does not grow, so the pencil and
   the warning sit beside the title in the all-rooms lane instead of
   drifting over the last room's column. */
.schedule-band .schedule-card-body {
    flex: 0 1 auto;
}

/* Draggables never join a text selection: a drag that starts inside a
   selection would carry the whole selection as its ghost, sidebar
   panels included. */
.schedule-card,
.schedule-pending {
    user-select: none;
}

/* Where the drop would land: the dragged session's footprint, dashed,
   in the hovered room (full width over the all-rooms lane). It takes
   no pointer events, or hovering it would cancel the drop. */
.schedule-drop-preview {
    display: none;
    z-index: 3;
    justify-content: flex-end;
    align-items: flex-end;
    margin: 1px;
    pointer-events: none;
    background: rgba(207, 226, 255, 0.55);
    border: 2px dashed #6ea8fe;
    border-radius: 0.35rem;
}
/* The minute count rides the edge being dragged, on its own chip, so
   it never sits over the card's title. */
.schedule-drop-label {
    margin: 0.15rem;
    padding: 0 0.35rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: #fff;
    background: #084298;
    border-radius: 0.25rem;
}
.schedule-drop-label:empty {
    display: none;
}
/* A band spans the whole grid, so a right-hand chip can sit off
   screen; its chip joins the band's own controls at the left edge. */
.schedule-drop-preview.schedule-drop-band {
    justify-content: flex-start;
}

/* The off-screen clone a drag's image is painted from: rendered (so
   Chrome can rasterize it) but far outside the viewport. Snapshotting
   the live list item dragged its neighbours into the picture. */
.schedule-drag-image {
    position: fixed;
    top: -200vh;
    left: 0;
    z-index: -1;
    pointer-events: none;
    background: var(--bs-body-bg, #fff);
}

/* The presenter's own rows on their schedule page. */
.schedule-mine {
    background: #f6faff;
    border-left: 0.25rem solid #6ea8fe;
}

/* A card whose working position differs from what the speakers see:
   dashed until the next Publish schedule. */
.schedule-card-dirty {
    border-style: dashed;
}

.schedule-card-pencilled {
    border-style: dotted;
    opacity: 0.75;
}
/* A closed short card has no top or bottom border to carry the dashes,
   so they are painted along its top edge, above the lettering, taking no
   row height. */
.schedule-card-short.schedule-card-dirty:not(:hover):not(:focus-within):not(.schedule-card-open) {
    background-image: repeating-linear-gradient(90deg, #6ea8fe 0 4px, transparent 4px 7px);
    background-size: 100% 1px;
    background-repeat: no-repeat;
    background-position: top;
}

/* Compact and Fit densities (design §10.2): one-line cards, the detail
   stays in the tooltip and the pencil. */
.schedule-density-compact .schedule-card {
    padding-top: 0;
    padding-bottom: 0;
    font-size: 0.7rem;
}
.schedule-density-compact .schedule-card-meta,
.schedule-density-compact .schedule-card-warnings {
    display: none;
}
.schedule-density-compact .schedule-card-title {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.schedule-density-compact .schedule-hour {
    font-size: 0.65rem;
}
/* At Compact and Fit heights a card under a quarter hour has a few
   pixels: a plain strip of colour, its title on hover or focus. */
.schedule-density-compact
    .schedule-card-short:not(:hover):not(:focus-within):not(.schedule-card-open) {
    font-size: 0;
}

/* The subscribe popover holds a whole URL. */
.schedule-feed-popover {
    width: 22rem;
    max-width: 90vw;
}

/* Fit shrinks the lettering with the rows: the text follows the
   computed row height, floored where it stops being readable. */
.schedule-density-fit .schedule-card {
    padding: 0 0.2rem;
    font-size: clamp(7px, calc(var(--schedule-row-height, 0.5rem) * var(--schedule-rows-per-quarter, 3) * 0.72), 0.7rem);
    line-height: 1.15;
    border-radius: 0.2rem;
}
.schedule-density-fit .schedule-hour {
    font-size: clamp(7px, calc(var(--schedule-row-height, 0.5rem) * var(--schedule-rows-per-quarter, 3) * 0.72), 0.65rem);
}
.schedule-density-fit .schedule-card-edit,
.schedule-density-fit .schedule-card .text-warning-emphasis[role="img"] {
    padding: 0 0.15rem;
    font-size: clamp(7px, calc(var(--schedule-row-height, 0.5rem) * var(--schedule-rows-per-quarter, 3) * 0.7), 0.7rem);
    line-height: 1.1;
}
/* An opened short card is read up close, whatever the density. */
.schedule-density-compact .schedule-card-short:hover,
.schedule-density-compact .schedule-card-short:focus-within,
.schedule-density-compact .schedule-card-short.schedule-card-open {
    padding: 0.1rem 0.3rem;
    font-size: 0.75rem;
    line-height: 1.25;
}
.schedule-density-compact .schedule-card-short:is(:hover, :focus-within, .schedule-card-open) .schedule-card-edit,
.schedule-density-compact .schedule-card-short:is(:hover, :focus-within, .schedule-card-open) .text-warning-emphasis[role="img"] {
    padding: 0 0.3rem;
    font-size: 0.7rem;
    line-height: 1.3;
}

/* The wide (spreadsheet) view breaks out of the page container: full
   viewport width, so every room column gets its share of the screen. */
.schedule-wide,
.page-wide {
    position: relative;
    left: 50%;
    width: 100vw;
    margin-left: -50vw;
    padding: 0 1.5rem;
}

/* The presenters' data view: a spreadsheet, headers that stay put. */
.presenter-data {
    font-size: 0.85rem;
    white-space: nowrap;
}

.presenter-data thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}
