/* PROMEMIO UI v3 components: application shell and page header. */

/* Application shell */
.pm-app {
    min-height: 100vh;
    display: grid;
    grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
    background: var(--color-bg);
}

.pm-sidebar {
    min-width: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    padding: var(--sidebar-pad-block-start) var(--sidebar-pad-inline) var(--sidebar-pad-block-end);
    background: var(--color-sidebar);
    border-right: 1px solid var(--color-line);
}

.pm-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--color-bg);
}

/* Brand: approved wordmark and clock mark (decision 0086). The row keeps one height in every layout. */
.pm-brand {
    display: flex;
    align-items: center;
    min-height: var(--brand-row-height);
    margin: var(--brand-margin);
}

.pm-brand a {
    display: block;
    min-width: 0;
    border-radius: var(--radius-icon);
}

.pm-brand-full {
    display: block;
    min-width: 0;
}

.pm-wordmark {
    display: block;
    width: var(--brand-logo-width);
    height: auto;
}

/* The clock mark is only shown in the icon rail. */
.pm-brand .pm-mark {
    display: none;
}

.pm-logo-text {
    fill: var(--color-text);
}

.pm-logo-accent {
    fill: var(--color-accent);
}

.pm-logo-hands {
    stroke: var(--color-on-accent);
}

.pm-logo-centre {
    fill: var(--color-on-accent);
}

/* Project switcher */
.pm-project-switcher {
    margin-bottom: var(--picker-margin-bottom);
}

.pm-project-picker {
    position: relative;
    min-height: var(--control-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--field-gap);
    padding: 0 var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    cursor: pointer;
}

.pm-project-picker:focus-within {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

:root[data-contrast="high"] .pm-project-picker:focus-within {
    outline-width: 3px;
}

.pm-project-picker-value {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.pm-project-picker-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pm-project-picker .pm-icon {
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    color: var(--color-text-muted);
}

.pm-project-picker-mark {
    display: none;
    flex: 0 0 auto;
}

.pm-project-picker-select {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

/* Navigation */
.pm-nav-label {
    margin: 0 var(--nav-item-gap) var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: .08em;
    text-transform: uppercase;
}

.pm-nav {
    display: grid;
    gap: var(--nav-gap);
}

.pm-nav a {
    min-height: var(--control-height);
    display: grid;
    grid-template-columns: var(--nav-icon-column) minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--nav-item-gap);
    padding: 0 var(--space-3);
    border-radius: var(--radius-control);
    color: var(--color-text-muted);
    text-decoration: none;
}

.pm-nav a:hover {
    color: var(--color-text);
    background: var(--color-hover);
    text-decoration: none;
}

.pm-nav a[aria-current="page"] {
    color: var(--color-text);
    background: var(--color-selected);
    font-weight: var(--weight-medium);
}

.pm-nav .pm-icon {
    width: var(--icon-size);
    height: var(--icon-size);
    color: var(--color-text-muted);
}

/* Account and logout */
.pm-sidebar-bottom {
    margin-top: auto;
}

.pm-account {
    margin-top: var(--space-3);
    padding: var(--account-pad);
    border-top: 1px solid var(--color-line);
}

.pm-account strong {
    display: block;
    font-weight: var(--weight-medium);
}

.pm-account span {
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

.pm-account-avatar {
    display: none;
}

/* Top-bar account avatar and its menu. The avatar is interactive, so it keeps
   the letter circle and adds a secondary-button boundary and a chevron. */
.pm-avatar-button {
    position: relative;
    min-height: var(--control-height);
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    flex: 0 0 auto;
    padding: 0 var(--space-2);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    background: var(--color-surface);
    color: var(--color-text);
}

.pm-avatar-button:hover {
    background: var(--color-subtle);
}

.pm-avatar-button:active {
    background: var(--color-selected);
}

.pm-avatar-circle {
    width: var(--topbar-avatar-size);
    height: var(--topbar-avatar-size);
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--color-subtle);
    color: var(--color-text);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}

.pm-avatar-chevron {
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    flex: 0 0 auto;
    color: var(--color-text-muted);
}

/* Tooltip: hidden until its host is hovered or keyboard-focused. Shared by the
   top-bar avatar; the icon-rail labels use the same surface treatment. */
.pm-tooltip {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* A trigger's tooltip is hidden while its menu is open (shared behaviour), so
   it never stays visible behind the menu surface. */
.pm-tooltip-host[aria-expanded="true"] > .pm-tooltip,
.pm-tooltip-host:has([data-ui-menu-trigger][aria-expanded="true"]) > .pm-tooltip {
    display: none;
}

.pm-tooltip-host:hover > .pm-tooltip,
.pm-tooltip-host:focus-visible > .pm-tooltip {
    position: absolute;
    z-index: 5;
    width: auto;
    height: auto;
    margin: 0;
    padding: var(--space-1) var(--space-2);
    overflow: visible;
    clip: auto;
    background: var(--color-popover);
    color: var(--color-text);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-small);
    box-shadow: var(--shadow-popover);
    white-space: nowrap;
}

.pm-tooltip--bottom {
    top: calc(100% + var(--space-2));
    inset-inline-end: 0;
}

/* Topbar. The bar is the query container of its own controls (decision 0091): large text leaves it less room
   than the viewport width suggests, so its controls take their compact forms by the bar's own width in rem
   (which follows the text size), keep one row while they fit and only then wrap onto further rows inside the
   bar instead of widening the page (B-37). No control shrinks below its content. */
.pm-topbar {
    container: pm-topbar / inline-size;
    min-height: var(--topbar-height);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3) var(--topbar-gap);
    padding: var(--space-2) var(--topbar-pad-inline);
    border-bottom: 1px solid var(--color-line);
}

.pm-top-actions {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-3);
}

.pm-menu-button {
    width: var(--control-height);
    height: var(--control-height);
    display: none;
    place-items: center;
    padding: 0;
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    background: var(--color-surface);
    color: var(--color-text);
}

.pm-menu-button:hover {
    color: var(--color-text);
    background: var(--color-subtle);
}

.pm-menu-button .pm-icon {
    width: var(--icon-size);
    height: var(--icon-size);
}

/* "Timer running" and the time never break inside a word; only a label wider than the whole bar would put the
   time on a second line of the chip. */
.pm-active-timer {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--control-height);
    padding: 0 var(--space-3);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-control);
    background: var(--color-surface);
    color: var(--color-text-muted);
    text-decoration: none;
    white-space: nowrap;
}

/* Chip and Stop stay side by side; Stop moves below the chip only when the two do not fit across the bar. */
.pm-active-timer-group {
    max-width: 100%;
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
}

.pm-active-timer-stop {
    margin: 0;
}

.pm-active-timer:hover {
    background: var(--color-subtle);
    text-decoration: none;
}

.pm-active-timer .pm-icon {
    flex: none;
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    color: var(--color-accent);
}

.pm-active-timer time {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 47.999em) {
    .pm-active-timer-label { display: none; }

    /* On phones the chip shows only the elapsed time so Stop stays beside it on one row. */
    .pm-active-timer .pm-icon { display: none; }
    .pm-active-timer { padding: 0 var(--space-2); }
    .pm-active-timer-stop .pm-button { padding-inline: var(--space-2); }
}
.pm-active-timer--compact .pm-active-timer-label { display: none; }

/* Compact forms by the bar's own width (decision 0091). Each threshold is the width one row of controls needs at
   100% text with an hh:mm:ss timer and the wider "Ctrl K" hint, in rem so it follows the text size: the full chip,
   Stop, the search field at its content width and the account button need 31.7rem; with the chip without its
   words 25.55rem, below which search becomes the icon button (search.css). Below 19.6rem even both compact forms
   need two rows. */
@container pm-topbar (max-width: 31.699rem) {
    .pm-active-timer-label { display: none; }
}

/* Search and account wrap as one unit, so when the controls no longer share one row chip and Stop take the first
   row and search and account the next, and no control is left alone on a row. While the search field can still
   grow (a wide bar) they are plain items of the actions row; once search is the icon button they are a group. */
.pm-search-account-group {
    display: contents;
    align-items: center;
    gap: var(--space-3);
}

@container pm-topbar (max-width: 25.549rem) {
    .pm-active-timer-group ~ .pm-search-account-group { display: flex; }
}

@media (max-width: 47.999em) {
    .pm-search-account-group { display: flex; }
}

/* Content and page header */
.pm-content {
    /* Full-width page frame (layout-width rules, 2026-09-26): header and
       toolbars span the whole content area; each page constrains only what
       must be constrained (readable text, forms, list rows without columns). */
    width: 100%;
    padding: var(--content-pad-top) clamp(var(--content-pad-inline-min), 3vw, var(--content-pad-inline-max)) var(--content-pad-bottom);
}

/* The title block shares the line with the page actions and wraps its words there, but it keeps at least
   40% of the header and never gets narrower than its longest word. When that no longer fits beside the
   actions (large text, a long title), the actions move below the title as on phones, so a title is never
   squeezed into a narrow column or broken inside a word (decision 0090). At 100% text and 48em or wider
   no header changes: every title there has more than 40% of the header beside its actions (45% at the
   least). Only a word wider than the whole header still breaks. */
.pm-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--header-gap);
    margin-bottom: var(--header-margin);
}

.pm-header > * {
    min-width: 0;
    overflow-wrap: anywhere;
}

.pm-header > :first-child {
    flex: 1 1 40%;
    min-width: auto;
    max-width: 100%;
}

/* Whole words set the title block's smallest width, so no text in it may break anywhere (base.css does that for spans and headings). */
.pm-header > :first-child,
.pm-header > :first-child * {
    overflow-wrap: break-word;
}

.pm-header h1 {
    margin: 0;
    font-size: var(--text-xl);
    line-height: var(--line-height-title);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-title);
}

.pm-subtitle {
    margin: var(--space-1) 0 0;
    color: var(--color-text-muted);
}

.pm-actions {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* Shared primitives used by the shell and page header */
.pm-button {
    min-height: var(--control-height);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0 var(--button-pad);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    background: var(--color-surface);
    color: var(--color-text);
    max-width: 100%;
    white-space: normal;
    text-decoration: none;
}

.pm-button:hover {
    background: var(--color-subtle);
    text-decoration: none;
}

.pm-button.primary {
    color: var(--color-on-accent);
    border-color: var(--color-accent);
    background: var(--color-accent);
}

.pm-button.primary:hover {
    border-color: var(--color-accent-hover);
    background: var(--color-accent-hover);
}

.pm-button.ghost {
    color: var(--color-text-muted);
    border-color: transparent;
    background: transparent;
}

.pm-button .pm-icon {
    width: var(--icon-size-small);
    height: var(--icon-size-small);
}

/* Continue on a Time entries row (Time and Today, decision 0071): the ghost button of Start on Today's plan rows,
   icon and text. Where the row's list is narrower than 30rem only the icon stays; the text remains its accessible name. */
.pm-continue {
    flex: none;
    white-space: nowrap;
}

@container (max-width: 29.999rem) {
    .pm-continue {
        width: var(--control-height);
        padding: 0;
    }

    .pm-continue .pm-continue-label {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }
}

.pm-icon-button {
    width: var(--control-height);
    height: var(--control-height);
    display: inline-grid;
    place-items: center;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-icon);
    background: transparent;
    color: var(--color-text-muted);
}

.pm-icon-button:hover {
    color: var(--color-text);
    background: var(--color-subtle);
}

.pm-icon-button .pm-icon {
    width: var(--icon-size);
    height: var(--icon-size);
}

/* One time of a range from promemio_format_time_range_html(): never broken inside (decision 0090). */
.pm-clock {
    white-space: nowrap;
}

.pm-tag {
    display: inline-flex;
    align-items: center;
    gap: 0;
    min-height: var(--tag-height);
    padding: 0 var(--space-2);
    border-radius: var(--radius-tag);
    background: var(--color-subtle);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    width: fit-content;
    max-width: 100%;
    white-space: normal;
}

.pm-tag .pm-dot {
    margin-inline-end: var(--space-1);
}

.pm-tag strong {
    font-weight: var(--weight-medium);
}

.pm-tag.accent {
    background: var(--color-accent-bg);
    color: var(--color-accent);
}

.pm-dot {
    width: var(--dot-size);
    height: var(--dot-size);
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--project-color, var(--color-project-graphite));
}

.pm-color-pink {
    --project-color: var(--color-project-mulberry);
}

.pm-color-purple {
    --project-color: var(--color-project-violet);
}

.pm-color-green {
    --project-color: var(--color-project-pine);
}

.pm-color-yellow {
    --project-color: var(--color-project-terracotta);
}

.pm-color-blue {
    --project-color: var(--color-project-harbor);
}

.pm-color-red {
    --project-color: var(--color-danger);
}

.pm-color-gray {
    --project-color: var(--color-project-graphite);
}

.pm-muted {
    color: var(--color-text-muted);
}

.pm-small {
    font-size: var(--text-xs);
}

.pm-placeholder {
    margin: 0;
    color: var(--color-text-muted);
}

/* Compact icon rail: 48em to below 61.25em */
@media (min-width: 48em) and (max-width: 61.249em) {
    .pm-app {
        grid-template-columns: var(--sidebar-rail-width) minmax(0, 1fr);
    }

    .pm-sidebar {
        overflow: visible;
        padding-inline: var(--sidebar-rail-pad-inline);
    }

    .pm-brand {
        justify-content: center;
        margin-inline: 0;
    }

    .pm-brand-full {
        display: none;
    }

    .pm-brand .pm-mark {
        display: block;
        width: var(--brand-mark-size);
        height: var(--brand-mark-size);
    }

    .pm-sidebar .pm-project-picker {
        justify-content: center;
        padding: 0;
        background: transparent;
        border: 0;
    }

    .pm-sidebar .pm-project-picker:focus-within {
        outline: none;
    }

    .pm-sidebar .pm-project-picker:focus-within .pm-project-picker-mark {
        outline: 2px solid var(--color-accent);
        outline-offset: 2px;
    }

    :root[data-contrast="high"] .pm-sidebar .pm-project-picker:focus-within .pm-project-picker-mark {
        outline-width: 3px;
    }

    .pm-sidebar .pm-project-picker-value {
        justify-content: center;
    }

    .pm-sidebar .pm-project-picker-mark {
        width: var(--control-height);
        height: var(--control-height);
        display: inline-grid;
        place-items: center;
        border-radius: 50%;
        background: var(--project-color, var(--color-project-graphite));
        color: var(--color-on-project);
        font-size: var(--text-base);
        font-weight: var(--weight-medium);
        line-height: 1;
    }

    .pm-sidebar .pm-project-picker-mark .pm-icon {
        width: var(--icon-size);
        height: var(--icon-size);
        color: inherit;
    }

    .pm-sidebar .pm-project-picker--all .pm-project-picker-mark {
        background: var(--color-surface);
        border: 1px solid var(--color-line-control);
        color: var(--color-text-muted);
    }

    .pm-sidebar .pm-project-picker > .pm-icon,
    .pm-sidebar .pm-project-picker .pm-dot,
    .pm-nav-label,
    .pm-account strong,
    .pm-account > span:not(.pm-account-avatar) {
        display: none;
    }

    .pm-sidebar .pm-project-picker-name {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }

    .pm-sidebar .pm-project-picker:hover .pm-project-picker-name,
    .pm-sidebar .pm-project-picker:focus-within .pm-project-picker-name {
        position: absolute;
        inset-inline-start: calc(100% + var(--space-2));
        top: 50%;
        z-index: 5;
        width: auto;
        height: auto;
        margin: 0;
        padding: var(--space-1) var(--space-2);
        overflow: visible;
        clip: auto;
        transform: translateY(-50%);
        background: var(--color-popover);
        color: var(--color-text);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-small);
        box-shadow: var(--shadow-popover);
        white-space: nowrap;
    }

    .pm-nav a {
        position: relative;
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        padding: 0;
    }

    .pm-nav-text {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }

    .pm-nav a:hover .pm-nav-text,
    .pm-nav a:focus-visible .pm-nav-text {
        position: absolute;
        inset-inline-start: calc(100% + var(--space-2));
        top: 50%;
        z-index: 5;
        width: auto;
        height: auto;
        margin: 0;
        padding: var(--space-1) var(--space-2);
        overflow: visible;
        clip: auto;
        transform: translateY(-50%);
        background: var(--color-popover);
        color: var(--color-text);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-small);
        box-shadow: var(--shadow-popover);
        white-space: nowrap;
    }

    .pm-account {
        padding-inline: 0;
        text-align: center;
    }

    .pm-account-avatar {
        width: var(--account-avatar-size);
        height: var(--account-avatar-size);
        display: inline-grid;
        place-items: center;
        margin-inline: auto;
        border-radius: 50%;
        background: var(--color-surface);
        color: var(--color-text);
        font-size: var(--text-xs);
        font-weight: var(--weight-medium);
    }
}

/* Mobile drawer */
.pm-drawer-overlay {
    position: fixed;
    inset: 0;
    z-index: 30;
    padding: 0;
    border: 0;
    background: var(--color-overlay);
}

@media (max-width: 47.999em) {
    .pm-app {
        grid-template-columns: minmax(0, 1fr);
    }

    .pm-menu-button {
        display: inline-grid;
    }

    .pm-sidebar {
        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        z-index: 40;
        width: min(var(--drawer-width), calc(100vw - var(--space-7)));
        min-height: 0;
        transform: translateX(-100%);
        /* Closed and off-screen, the drawer is hidden, which takes its links out of the Tab order and the
           accessibility tree; the hiding waits for the slide-out to end. */
        visibility: hidden;
        transition: transform .18s ease, visibility 0s linear .18s;
    }

    .pm-sidebar[data-open="true"] {
        transform: translateX(0);
        visibility: visible;
        transition: transform .18s ease;
    }

    .pm-topbar {
        padding-inline: var(--space-4);
    }

    .pm-content {
        padding-inline: var(--space-4);
    }

    .pm-header {
        align-items: flex-start;
        flex-wrap: wrap;
    }

    .pm-header .pm-actions {
        width: 100%;
    }
}

@media (max-width: 23.999em) {
    .pm-topbar { gap: var(--space-2); padding-inline: var(--space-3); }
    .pm-top-actions,
    .pm-search-account-group { gap: var(--space-2); }
}

/* Buttons: danger and disabled variants */
.pm-button.danger {
    color: var(--color-danger);
    border-color: transparent;
    background: transparent;
}

.pm-button.danger:not(:disabled):hover {
    background: var(--color-danger-bg);
    text-decoration: none;
}

.pm-button.danger-fill {
    color: var(--color-on-accent);
    border-color: var(--color-danger);
    background: var(--color-danger);
}

.pm-button.danger-fill:not(:disabled):hover {
    border-color: color-mix(in srgb, var(--color-danger) 88%, var(--color-text));
    background: color-mix(in srgb, var(--color-danger) 88%, var(--color-text));
}

.pm-button:disabled,
.pm-button[disabled] {
    color: var(--color-text-disabled);
    border-color: var(--color-line);
    background: var(--color-subtle);
    cursor: not-allowed;
}

.pm-button.ghost:disabled,
.pm-button.danger:disabled {
    border-color: transparent;
    background: transparent;
}

.pm-icon-button:disabled,
.pm-icon-button[disabled] {
    color: var(--color-text-disabled);
    background: transparent;
    cursor: not-allowed;
}

/* Labelled field, select, picker chip, search */
.pm-label {
    display: block;
    margin-bottom: var(--space-1);
    color: var(--color-text);
    font-weight: var(--weight-medium);
}

.pm-input,
.pm-select,
.pm-textarea {
    width: 100%;
    min-height: var(--control-height);
    padding: 0 var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    color: var(--color-text);
}

.pm-select {
    appearance: none;
    padding-right: var(--space-6);
}

.pm-textarea {
    min-height: var(--control-height);
    padding-block: var(--space-2);
    resize: vertical;
}

.pm-input:hover,
.pm-select:hover,
.pm-textarea:hover {
    border-color: var(--color-line-strong);
}

.pm-input:disabled,
.pm-select:disabled,
.pm-textarea:disabled {
    color: var(--color-text-disabled);
    background: var(--color-subtle);
    cursor: not-allowed;
}

.pm-input.is-error,
.pm-select.is-error,
.pm-textarea.is-error,
.pm-input[aria-invalid="true"],
.pm-select[aria-invalid="true"],
.pm-textarea[aria-invalid="true"] {
    border-color: var(--color-danger);
}

.pm-field-error {
    margin: var(--space-1) 0 0;
    color: var(--color-danger);
    font-size: var(--text-xs);
}

.pm-field-help {
    margin: var(--space-1) 0 0;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

.pm-field-wrap {
    min-width: 0;
}

/* Shared due-date shortcuts used by task and to-do editors. */
.pm-date-quick-picks {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-2);
    /* The first button's text starts on the field's left edge; its padding and border stay as hover area outside it (B-11). */
    margin-inline-start: calc(-1 * (var(--space-2) + 1px));
}

.pm-date-quick-picks .pm-button {
    min-height: var(--control-height-compact);
    padding-inline: var(--space-2);
    font-size: var(--text-sm);
}

.pm-date-quick-picks .pm-button[aria-pressed="true"] {
    color: var(--color-text);
    background: var(--color-selected);
}

/* Shared time-entry fields: Today's inline manual form, Time's add dialog and
   every Time inline editor (decision 0066 Stage 2). */
.pm-time-fields {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-3);
}

.pm-time-field {
    display: grid;
    min-width: 0;
    align-content: start;
    gap: var(--space-1);
}

.pm-time-field > .pm-input,
.pm-time-field .pm-select,
.pm-time-field .pm-textarea {
    width: 100%;
    min-width: 0;
}

.pm-time-field .pm-field-error {
    margin: 0;
}

.pm-time-end {
    display: flex;
    min-width: 0;
    gap: var(--space-2);
}

.pm-time-end .pm-input {
    flex: 1 1 auto;
    min-width: 0;
}

.pm-time-end .pm-button {
    flex: none;
}

.pm-time-fields .pm-time-comment {
    grid-column: 1 / -1;
}

/* The manual form's fields fold by the module's own width (owner review,
   2026-09-29): on a half-width Timer the date takes the full row and Start and End
   share the next one; in a wide card all three share one row; on a narrow card they
   stack, so no field is ever narrower than its content (checklist point 16). */
.pm-timer-manual .pm-time-fields {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.pm-timer-manual .pm-time-fields > .pm-time-field:first-child {
    grid-column: 1 / -1;
}

@container (min-width: 32rem) {
    .pm-timer-manual .pm-time-fields {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .pm-timer-manual .pm-time-fields > .pm-time-field:first-child {
        grid-column: auto;
    }
}

@container (max-width: 21.999rem) {
    .pm-timer-manual .pm-time-fields {
        grid-template-columns: minmax(0, 1fr);
    }

    .pm-timer-manual .pm-time-fields > .pm-time-field:first-child {
        grid-column: auto;
    }
}

.pm-dialog-body .pm-time-end .pm-input {
    flex: 1 1 6rem;
}

.pm-dialog-body .pm-time-end .pm-button {
    margin-inline-start: auto;
}

[data-time-live]:empty,
[data-today-live]:empty {
    display: none;
}

/* Without JavaScript the end date stays reachable for overnight entries. */
html:not(.js) [data-time-end-date][hidden] {
    display: grid !important;
}

/* Add time / Edit time dialogs (Time and Calendar) and Time's inline editor (B-29,
   decision 0072): Start date | Start | End, then Project | Activity | Task, then
   Comment. Each group stacks in that order when the form is narrower than 30rem, so
   a group is never split across rows. */
.pm-time-form-host,
.pm-time-editor {
    container: pm-time-form / inline-size;
}

.pm-time-form-host .pm-time-fields,
.pm-time-editor .pm-time-fields {
    grid-template-columns: minmax(0, 1fr);
}

@container pm-time-form (min-width: 30rem) {
    .pm-time-form-host .pm-time-fields,
    .pm-time-editor .pm-time-fields {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    /* An overnight entry's End date takes its own row and Project starts the next one. */
    .pm-time-form-host .pm-time-end-date:not([hidden]) + .pm-time-field,
    .pm-time-editor .pm-time-end-date:not([hidden]) + .pm-time-field {
        grid-column: 1;
    }
}

@media (max-width: 47.999em) {
    .pm-time-fields {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 27.5em) {
    .pm-time-fields {
        grid-template-columns: minmax(0, 1fr);
    }
}

.pm-select-wrap {
    position: relative;
    display: block;
}

.pm-select-wrap .pm-icon {
    position: absolute;
    top: 50%;
    right: var(--space-3);
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    color: var(--color-text-muted);
    pointer-events: none;
    transform: translateY(-50%);
}

.pm-field {
    min-height: var(--control-height);
    min-width: var(--field-min-width);
    display: inline-flex;
    align-items: center;
    gap: var(--field-gap);
    padding: 0 var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    color: var(--color-text);
    max-width: 100%;
    white-space: normal;
}

button.pm-field {
    justify-content: space-between;
    text-align: left;
}

.pm-field:hover {
    background: var(--color-subtle);
}

.pm-field .pm-icon {
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    color: var(--color-text-muted);
}

.pm-field.search {
    min-width: min(var(--field-search-min), 100%);
    flex: 1 1 var(--field-search-min);
    color: var(--color-text-muted);
}

.pm-search {
    position: relative;
    min-width: min(var(--field-search-min), 100%);
    max-width: var(--field-search-max);
    flex: 1 1 var(--field-search-min);
}

.pm-search .pm-input {
    padding-left: var(--space-6);
}

.pm-search .pm-icon {
    position: absolute;
    top: 50%;
    left: var(--space-3);
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    color: var(--color-text-muted);
    pointer-events: none;
    transform: translateY(-50%);
}

/* Checkbox */
.pm-check {
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.pm-check-input,
.pm-switch-input,
.pm-segmented-option input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.pm-check-box {
    width: var(--check-size);
    height: var(--check-size);
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-check);
    background: var(--color-surface);
    color: transparent;
}

.pm-check-box .pm-icon {
    width: var(--icon-size-check);
    height: var(--icon-size-check);
    stroke-width: 2.2;
}

.pm-check-input:checked + .pm-check-box {
    color: var(--color-success);
    border-color: var(--color-success);
    background: var(--color-success-bg);
}

.pm-check-input:focus-visible + .pm-check-box {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.pm-check-input:disabled + .pm-check-box {
    border-color: var(--color-line);
    background: var(--color-subtle);
}

.pm-check-label {
    min-width: 0;
}

/* Segmented control */
.pm-segmented {
    min-width: 0;
    display: inline-grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    margin: 0;
    padding: var(--segmented-pad);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-control);
    background: var(--color-sidebar);
}

.pm-segmented-option {
    position: relative;
    display: inline-flex;
    min-width: 0;
}

.pm-segmented-option span {
    min-height: var(--control-height-compact);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 var(--segmented-option-pad);
    border: 0;
    border-radius: var(--radius-segmented);
    background: transparent;
    color: var(--color-text-muted);
    white-space: nowrap;
}

.pm-segmented-option input:checked + span {
    color: var(--color-text);
    background: var(--color-surface);
    box-shadow: var(--shadow-segmented);
    font-weight: var(--weight-medium);
}

.pm-segmented-option input:focus-visible + span {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
    z-index: 1;
}

.pm-segmented-option input:disabled + span {
    color: var(--color-text-disabled);
    background: transparent;
    box-shadow: none;
}

/* Switch */
.pm-switch {
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.pm-switch-track {
    width: var(--switch-width);
    height: var(--switch-height);
    display: block;
    flex: 0 0 auto;
    padding: var(--switch-pad);
    border-radius: var(--radius-pill);
    background: var(--color-line-strong);
    transition: background .15s ease;
}

.pm-switch-track::after {
    content: "";
    display: block;
    width: var(--switch-thumb);
    height: var(--switch-thumb);
    border-radius: 50%;
    background: var(--color-surface);
    box-shadow: var(--shadow-switch-thumb);
    transition: transform .15s ease;
}

.pm-switch-input:checked + .pm-switch-track {
    background: var(--color-accent);
}

.pm-switch-input:checked + .pm-switch-track::after {
    transform: translateX(var(--switch-offset));
}

.pm-switch-input:focus-visible + .pm-switch-track {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.pm-switch-input:disabled + .pm-switch-track {
    opacity: .5;
}

/* File field (decision 0085). Without JavaScript the real input shows unchanged and the button and
   name are hidden, so what was chosen stays visible in the browser's own control. With JavaScript the
   input is an invisible overlay on the whole field (a click anywhere opens the picker; it stays the
   focusable, labelled control) and a secondary button plus the chosen name(s) are drawn over it. */
.pm-file-button,
.pm-file-name {
    display: none;
}

html.js .pm-file {
    position: relative;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
}

html.js .pm-file-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
    opacity: 0;
    cursor: pointer;
}

html.js .pm-file-input:disabled {
    cursor: not-allowed;
}

html.js .pm-file-button {
    display: inline-flex;
    flex: none;
}

html.js .pm-file-name {
    min-width: 0;
    display: block;
    flex: 1 1 var(--field-min-width);
    color: var(--color-text-muted);
    font-size: var(--text-sm);
    overflow-wrap: anywhere;
}

html.js .pm-file-input:hover ~ .pm-file-button {
    background: var(--color-subtle);
}

html.js .pm-file-input:focus-visible ~ .pm-file-button {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

html.js[data-contrast="high"] .pm-file-input:focus-visible ~ .pm-file-button {
    outline-width: 3px;
}

html.js .pm-file-input:disabled ~ .pm-file-button {
    color: var(--color-text-disabled);
    border-color: var(--color-line);
    background: var(--color-subtle);
    cursor: not-allowed;
}

html.js .pm-file-input[aria-invalid="true"] ~ .pm-file-button {
    border-color: var(--color-danger);
}

/* Module panel */
.pm-panel {
    min-width: 0;
    padding: var(--panel-pad);
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-panel);
    box-shadow: var(--shadow-card);
}

.pm-panel-head {
    min-height: var(--control-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-bottom: var(--panel-head-margin);
}

.pm-panel-head > * {
    min-width: 0;
}

.pm-panel-head h2 {
    margin: 0;
    font-size: var(--panel-title-font);
    line-height: var(--line-height-title-md);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-title-md);
}

.pm-panel-count {
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The header link does not break beside the title; when it does not fit there it moves
   below as one piece (B-10 review). Only when it is wider than the whole panel head (large
   text on a phone) does its label wrap instead of leaving the panel (decision 0090); the cap
   counts the negative margins below. */
.pm-panel-action {
    flex: none;
    max-width: calc(100% + 2 * (var(--button-pad) + 1px));
}

.pm-panel-action .pm-button {
    text-align: start;
}

/* A ghost link in a panel header keeps its hover area outside the content edge, so its
   text starts on the title's left edge when it wraps below the title and ends on the
   right content edge beside it (B-11). */
.pm-panel-head > .pm-button.ghost,
.pm-panel-head > .pm-panel-action {
    margin-inline: calc(-1 * (var(--button-pad) + 1px));
}

.pm-panel-body {
    min-width: 0;
}

/* Bordered list and data row */
.pm-list {
    min-width: 0;
    overflow: hidden;
    background: var(--color-surface);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
}

.pm-list-plain {
    background: transparent;
    border: 0;
    border-radius: 0;
    overflow: visible;
}

.pm-row {
    position: relative;
    min-height: var(--row-height);
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--row-gap);
    padding: var(--row-pad-block) var(--row-pad-inline);
    border-bottom: 1px solid var(--color-line);
}

.pm-row:not(.danger):not(:has(~ .pm-row)) {
    border-bottom: 0;
}

.pm-row > *,
.pm-row-main,
.pm-row-copy {
    min-width: 0;
}

.pm-row-main {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

/* A project dot leads the title line, not the middle of a tall row (B-11). */
.pm-row-main > .pm-dot {
    align-self: flex-start;
    margin-top: calc((1lh - var(--dot-size)) / 2);
}

.pm-row-copy strong {
    display: block;
    font-weight: var(--weight-medium);
}

.pm-row-copy .pm-small {
    display: block;
}

.pm-row-meta {
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

.pm-row-meta > span:not(.pm-tag),
.pm-row-meta > time {
    white-space: nowrap;
}

.pm-row-actions {
    position: absolute;
    inset-inline-end: var(--row-pad-inline);
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding-inline-start: var(--space-2);
    border-radius: var(--radius-control);
    background: var(--color-surface);
    opacity: 0;
    pointer-events: none;
}

.pm-row:hover .pm-row-actions,
.pm-row:focus-within .pm-row-actions {
    opacity: 1;
    pointer-events: auto;
}

/* The transform makes the row actions a stacking context, so their open menu's own z-index cannot lift it over the
   rows that follow (a click on Delete landed on the next row). While a menu is open the actions are lifted instead. */
.pm-row-actions:has([aria-haspopup="menu"][aria-expanded="true"]) {
    z-index: 1;
}

:root[data-actions="always"] .pm-row-actions {
    position: static;
    transform: none;
    padding-inline-start: 0;
    background: transparent;
    opacity: 1;
    pointer-events: auto;
}

.pm-row.danger {
    background: var(--color-danger-bg);
    border: 1px solid color-mix(in srgb, var(--color-danger) 20%, var(--color-line));
    border-radius: var(--radius-danger-row);
}

.pm-row.danger .pm-row-meta {
    color: var(--color-danger);
}

.pm-row-time {
    min-width: 0;
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pm-row-title {
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-weight: var(--weight-medium);
    text-align: left;
}

.pm-row-title:hover {
    text-decoration: underline;
}

/* Group label */
.pm-section-label {
    margin: var(--section-label-margin-top) var(--space-2) var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
}

.pm-panel-body > .pm-section-label:first-of-type {
    margin-top: 0;
}

/* Neutral "Coming soon" state for modules that are not available yet. */
.pm-coming-soon {
    display: inline-flex;
    align-items: center;
    min-height: var(--tag-height);
    padding: 0 var(--space-2);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-subtle);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
    white-space: nowrap;
}

/* Filter bar */
.pm-toolbar {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    padding: var(--toolbar-pad-block) var(--toolbar-pad-inline);
    margin-bottom: var(--toolbar-margin-bottom);
    background: var(--color-subtle);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
}

.pm-filters {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.pm-toolbar > .pm-filters {
    flex: 1 1 auto;
}

.pm-toolbar > .pm-filters + .pm-filters {
    flex: 0 0 auto;
}

.pm-link {
    color: var(--color-accent);
    font-weight: var(--weight-medium);
    white-space: nowrap;
}

/* Settings-style sub-navigation */
.pm-subnav {
    min-width: 0;
    display: grid;
    gap: var(--space-1);
    align-self: start;
    position: sticky;
    top: var(--space-5);
}

.pm-subnav-link {
    min-height: var(--control-height);
    display: flex;
    align-items: center;
    padding: 0 var(--space-3);
    border-radius: var(--radius-icon);
    color: var(--color-text-muted);
    text-decoration: none;
}

.pm-subnav-link:hover {
    color: var(--color-text);
    background: var(--color-hover);
    text-decoration: none;
}

.pm-subnav-link[aria-current="true"] {
    color: var(--color-text);
    background: var(--color-selected);
    font-weight: var(--weight-medium);
}

/* Menu */
.pm-menu-wrap {
    position: relative;
    display: inline-flex;
}

.pm-menu {
    position: absolute;
    top: calc(100% + var(--space-1));
    inset-inline-end: 0;
    z-index: 20;
    min-width: min(var(--menu-min-width), calc(100vw - 2 * var(--space-2)));
    max-width: calc(100vw - 2 * var(--space-2));
    padding: var(--space-1);
    background: var(--color-popover);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-control);
    box-shadow: var(--shadow-popover);
}

/* A menu opened inside a scrolling region that would clip it (the Tasks board, the Notes sections
   column) is moved to the body by menu.js and positioned against the viewport. */
.pm-menu.is-portaled {
    position: fixed;
    inset: auto;
    z-index: 30;
    max-height: calc(100dvh - var(--space-4));
    overflow-y: auto;
}

/* Menu opened on a trigger near the start of a row (the note meta project),
   so it stays inside the viewport instead of extending past the left edge
   (the reference's .pm-menu.start). */
.pm-menu.start {
    inset-inline-end: auto;
    inset-inline-start: 0;
}

.pm-menu-item {
    width: 100%;
    min-height: var(--control-height);
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 0 var(--space-3);
    border: 0;
    border-radius: var(--radius-control);
    background: transparent;
    color: var(--color-text);
    text-align: left;
    text-decoration: none;
}

.pm-menu-item:hover,
.pm-menu-item:focus-visible {
    background: var(--color-hover);
    text-decoration: none;
}

.pm-menu-item.danger {
    color: var(--color-danger);
}

/* The check marks the current choice (for example the note's project); it is a
   second signal next to aria-checked and never the only one. It sits in a fixed
   slot at the start of the item so dots and labels line up in one left-aligned
   column; the slot is reserved and empty when the item is not selected. */
.pm-menu-check {
    display: block;
    flex: 0 0 auto;
    width: var(--icon-size);
    height: var(--icon-size);
    color: var(--color-accent);
    visibility: hidden;
}

.pm-menu-item[aria-checked="true"] .pm-menu-check {
    visibility: visible;
}

/* Fixed media column: the project dot, or the empty slot that keeps the icons
   and labels of a menu that contains radios in the same left-aligned column. */
.pm-menu-icon {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    width: var(--icon-size);
    height: var(--icon-size);
}

/* A mouse-opened menu keeps focus on its first item for arrow keys, but the
   ring stays hidden until the first key press (menu.js removes this class). */
.pm-menu.is-pointer-open .pm-menu-item:focus-visible {
    outline: none;
}

.pm-menu-label {
    padding: var(--space-1) var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}

.pm-menu-divider {
    height: 1px;
    margin: var(--space-1) 0;
    background: var(--color-line);
}

/* Dialog */
.pm-dialog-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: var(--color-overlay);
}

.pm-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    z-index: 61;
    width: min(var(--dialog-width-custom, var(--dialog-width)), calc(100vw - 2 * var(--space-5)));
    max-height: min(var(--dialog-max-height), calc(100dvh - var(--space-7)));
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    overflow: hidden;
    background: var(--color-popover);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-dialog);
    box-shadow: var(--shadow-popover);
    transform: translate(-50%, -50%);
}

/* The dialog form is a layout-transparent wrapper so the head, body and footer
   remain the dialog grid rows while the whole dialog is one form. */
.pm-dialog-form {
    display: contents;
}

.pm-dialog-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-4);
    align-items: start;
    padding: var(--dialog-head-pad);
    border-bottom: 1px solid var(--color-line);
}

.pm-dialog-head h2 {
    margin: 0;
    font-size: var(--panel-title-font);
    line-height: var(--line-height-title-md);
    font-weight: var(--weight-medium);
    letter-spacing: var(--tracking-title-md);
}

.pm-dialog-head p {
    margin: var(--space-1) 0 0;
    color: var(--color-text-muted);
}

/* The close button is centred on the title's first line: the button is taller than
   the line, so it takes a negative top margin of half the difference. */
.pm-dialog:not(.pm-dialog--search) .pm-dialog-head > .pm-icon-button {
    margin-top: calc((var(--panel-title-font) * var(--line-height-title-md) - var(--control-height)) / 2);
}

.pm-dialog-body {
    min-width: 0;
    overflow-y: auto;
    padding: var(--dialog-body-pad);
}

.pm-dialog-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--dialog-foot-pad);
    border-top: 1px solid var(--color-line);
    background: var(--color-subtle);
    flex-wrap: wrap;
}

@media (max-width: 47.999em) {
    .pm-dialog {
        top: auto;
        bottom: 0;
        left: 0;
        width: 100%;
        max-height: 88vh;
        max-height: 88dvh;
        transform: none;
        border-radius: var(--radius-dialog) var(--radius-dialog) 0 0;
        grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
    }

    .pm-dialog-head {
        min-height: 0;
        max-height: 30dvh;
        overflow-y: auto;
        padding: var(--dialog-sheet-head-pad);
    }

    .pm-dialog-body {
        min-height: 0;
        padding: var(--dialog-sheet-body-pad);
    }

    .pm-dialog-foot {
        min-height: 0;
        max-height: 30dvh;
        overflow-y: auto;
        padding: var(--dialog-sheet-foot-pad);
        padding-bottom: calc(.875rem + env(safe-area-inset-bottom));
    }
}

/* Inline edit */
.pm-inline-edit {
    margin-top: var(--space-2);
    padding: var(--space-3);
    background: var(--color-subtle);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-card);
}

.pm-inline-edit-fields {
    min-width: 0;
    display: grid;
    gap: var(--space-3);
}

.pm-inline-edit-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-3);
    flex-wrap: wrap;
}

.pm-inline-edit-danger {
    min-width: 0;
    max-width: 100%;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.pm-inline-edit-buttons {
    min-width: 0;
    max-width: 100%;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
    flex-wrap: wrap;
}

/* Status message. The bottom margin is the shared page-block gap, so a status
   message never sits glued to the block below it on any page (B-01). */
.pm-status {
    margin: 0 0 var(--space-4);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-control);
}

.pm-status-success {
    background: var(--color-success-bg);
    color: var(--color-success);
}

.pm-status-error {
    background: var(--color-danger-bg);
    color: var(--color-danger);
}

.pm-status-info {
    background: var(--color-subtle);
    color: var(--color-text-muted);
}

.pm-status-link {
    color: inherit;
    font-weight: var(--weight-medium);
    text-decoration: underline;
}

/* Empty state */
.pm-empty {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-3);
}

.pm-empty p {
    margin: 0;
    color: var(--color-text-muted);
}

/* A text link in an empty state (a pointer to the other page) sits directly under the sentence and keeps a control-height touch target below its text. */
.pm-empty a:not(.pm-button) {
    display: inline-flex;
    align-items: flex-start;
    min-height: var(--control-height);
}

/* Archived section */
.pm-archived {
    margin-top: var(--space-5);
}

.pm-archived summary {
    color: var(--color-text-muted);
    font-weight: var(--weight-medium);
    cursor: pointer;
}

.pm-archived[open] summary {
    margin-bottom: var(--space-2);
}

/* Keyboard reorder */
.pm-reorder-handle {
    min-width: 0;
    flex: 1 1 auto;
    text-align: left;
}

.pm-reorder-status {
    min-height: var(--reorder-status-min-height);
    margin: var(--space-2) 0 0;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
}

/* Module grid (Today layout, B-02): each stored layout row is one line. A wide
   module fills its line; two half modules share it, and a half module that is
   alone in its line stays half width. Module widths never change with the
   viewport; below 48em every line stacks to one full-width column. The grid is
   also the query container of its lines (decision 0090): media queries do not
   follow the text size, so at large text a line narrower than 39rem stacks too. */
.pm-modules {
    min-width: 0;
    display: grid;
    gap: var(--module-gap);
    container: pm-modules / inline-size;
}

.pm-module-line {
    min-width: 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--split-gap);
    align-items: stretch;
}

.pm-module {
    min-width: 0;
    display: flex;
    flex-direction: column;
    /* The module itself is the query container: the timer reflows by its own
       width, so a half-width timer behaves like a narrow full-width one. */
    container-type: inline-size;
}

.pm-module > * {
    min-width: 0;
    flex: 1 1 auto;
}

.pm-module-wide {
    grid-column: 1 / -1;
}

/* 39rem is just below the narrowest line at 100% text and 48em or wider (40.125rem: 768px with
   the icon rail), with room for a classic scrollbar, so 100% text never stacks here and two half
   modules are never narrower than they are at 100% text (decision 0090). */
@container pm-modules (max-width: 38.999rem) {
    .pm-module-line {
        grid-template-columns: minmax(0, 1fr);
        row-gap: var(--module-gap);
    }
}

/* Timer. One grid at every width (B-11): the comment input and the picker row span
   the card, the manual-entry toggle and the elapsed/Start group share the next row
   (toggle at the left content edge, group at the right), and the manual form opens
   below that row. Rows are spaced by margins so a hidden item leaves no gap. */
.pm-timer {
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    /* Content stacks from the top; a taller card (equal-height line) leaves the
       extra space at the bottom instead of a band between the rows (B-10 review). */
    align-content: start;
    column-gap: var(--timer-gap);
    padding: var(--timer-pad);
    background: var(--color-accent-bg);
    border: 1px solid color-mix(in srgb, var(--color-accent) 18%, var(--color-line));
    border-radius: var(--radius-panel);
}

/* The form has no box of its own: its children are the timer grid's items. */
.pm-timer-main {
    display: contents;
}

.pm-timer-comment-field {
    min-width: 0;
    grid-column: 1 / -1;
}

.pm-timer-comment {
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--timer-input-gap);
    min-height: var(--timer-input-min-height);
    padding: 0 var(--timer-input-pad);
    background: var(--color-surface);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-timer-input);
    color: var(--color-text-muted);
    font-size: var(--timer-input-font);
}

.pm-timer-comment:focus-within {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

:root[data-contrast="high"] .pm-timer-comment:focus-within {
    outline-width: 3px;
}

.pm-timer-comment .pm-icon {
    width: var(--icon-size-large);
    height: var(--icon-size-large);
    flex: 0 0 auto;
    color: var(--color-accent);
}

.pm-timer-comment input {
    min-width: 0;
    flex: 1 1 auto;
    border: 0;
    background: transparent;
    color: var(--color-text);
    font-size: inherit;
}

.pm-timer-comment input:focus-visible {
    outline: none;
}

.pm-timer-filters {
    min-width: 0;
    grid-column: 1 / -1;
    display: flex;
    /* Top-aligned: an in-page field error under one picker grows its field and must
       never move the other controls in the row (owner bug, 2026-09-29). */
    align-items: flex-start;
    gap: var(--space-2);
    margin-top: var(--timer-input-gap);
    flex-wrap: wrap;
}

/* The pickers on one row share its width in equal columns and the row ends on the
   same right edge as the comment input and the Start button (B-10 review, B-11); a
   row too narrow for another column wraps it and it fills that row. */
.pm-timer-filters .pm-picker-field {
    flex: 1 1 var(--timer-picker-basis);
}

.pm-timer-filters .pm-picker {
    width: 100%;
}

/* A selected name wider than its select wraps between words instead of being cut off (large
   text; at 100% text every name that fits stays on one line); only a word wider than the
   select still breaks (bug batch 3). */
.pm-timer-filters .pm-picker select {
    flex: 1 1 auto;
    min-width: 0;
    white-space: normal;
    overflow-wrap: break-word;
}

/* A Timer module narrower than 12rem (large text on a phone; at 100% text the narrowest
   module is 18rem) leaves too little room beside the dot and the chevron for one word, so
   the name takes its own line under them (bug batch 3). */
@container (max-width: 11.999rem) {
    .pm-timer-filters .pm-picker {
        flex-wrap: wrap;
        row-gap: var(--space-1);
        padding-block: var(--space-2);
    }

    .pm-timer-filters .pm-picker select {
        order: 1;
        flex-basis: 100%;
    }

    .pm-timer-filters .pm-picker-chevron {
        margin-inline-start: auto;
    }
}

/* The ghost button's icon starts on the card's content edge, the same x as the input
   above it, so the padding and border stay as hover area outside the content edge (B-11). */
.pm-timer-manual-toggle {
    width: auto;
    height: auto;
    /* The height of the Start button beside it, so the row does not change height
       when the manual form hides the elapsed/Start group. */
    min-height: var(--control-height);
    grid-column: 1;
    margin-top: var(--space-3);
    margin-inline-start: calc(-1 * (var(--space-3) + 1px));
    padding: 0 var(--space-3);
    justify-self: start;
    justify-content: center;
    gap: var(--space-2);
    border-radius: var(--radius-control);
}

.pm-timer-manual-toggle .pm-icon {
    width: var(--icon-size-small);
    height: var(--icon-size-small);
}

/* The toggle is the manual form's state: active while the form is open, so it is
   never a second "Add time" action (owner review, 2026-09-29). */
.pm-timer-manual-toggle[aria-expanded="true"] {
    color: var(--color-text);
    background: var(--color-selected);
}

.pm-timer-manual {
    min-width: 0;
    grid-column: 1 / -1;
    display: grid;
    gap: var(--space-3);
    /* The standard gap between the toggle and the form's first label (B-11). */
    margin-top: var(--space-3);
}

.pm-timer-manual[hidden] {
    display: none;
}

.pm-timer-manual-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
}

/* A stretched card (equal-height line, B-11 owner decision) keeps the toggle and the
   elapsed/Start row at the card's bottom, so the free space falls between the pickers
   and that row. With the manual form open the natural order applies. */
.pm-timer:has(.pm-timer-manual[hidden]) {
    grid-template-rows: auto auto 1fr;
}

.pm-timer:has(.pm-timer-manual[hidden]) .pm-timer-manual-toggle,
.pm-timer:has(.pm-timer-manual[hidden]) .pm-timer-time {
    align-self: end;
}

.pm-timer-time {
    min-width: var(--timer-time-min);
    grid-column: 2;
    grid-row: 3;
    margin-top: var(--space-3);
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--timer-time-gap);
    font-size: var(--timer-elapsed-font);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pm-timer-elapsed {
    font-size: var(--timer-elapsed-font);
    font-weight: var(--weight-body);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* A Timer card narrower than 9.5rem (large text on a phone; at 100% text the narrowest card is
   18rem) shows the figure at --text-lg, so 00:00:00 stays inside the card (decision 0090). */
@container (max-width: 9.5rem) {
    .pm-timer-time,
    .pm-timer-elapsed {
        font-size: var(--text-lg);
    }
}

/* Below 27em of the module (the body text is 14px, so 378px: a phone, or text
   scaling) the elapsed/Start group takes its own row under the toggle and spreads to
   both content edges. Wider, the toggle and the group fit on one row. */
@container (max-width: 27em) {
    .pm-timer {
        grid-template-columns: minmax(0, 1fr);
    }

    /* The elapsed time and Start share a row while they fit; at large text Start wraps under
       the time at the row's right edge instead of overlapping it (B-37). */
    .pm-timer-time {
        min-width: 0;
        grid-column: 1;
        grid-row: auto;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
    }

    /* Start, or the form around Stop while a timer runs. */
    .pm-timer-time > :not(.pm-timer-elapsed) {
        margin-inline-start: auto;
    }

    /* Folded: the toggle row takes the free space and both rows stay at the bottom. */
    .pm-timer:has(.pm-timer-manual[hidden]) {
        grid-template-rows: auto auto 1fr auto;
    }

    .pm-timer:has(.pm-timer-manual[hidden]) .pm-timer-time {
        align-self: center;
    }
}

/* Picker chip. One column, so the field error always sits under its own control
   and can never widen the field or move it in the pickers row (owner bug,
   2026-09-29). */
.pm-picker-field {
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2);
}

.pm-picker-field .pm-field-error {
    margin: 0;
}

.pm-timer-comment + .pm-field-error {
    margin: var(--space-1) 0 0;
}

.pm-timer-start {
    flex: none;
    /* A standard button, not a display figure: it sits in the big time row and must
       not inherit --timer-elapsed-font (checklist point 9). */
    font-size: var(--text-base);
}

.pm-picker {
    min-width: 0;
    max-width: 100%;
    min-height: var(--timer-chip-height);
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--timer-chip-gap);
    padding: 0 var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
}

.pm-picker:hover {
    border-color: var(--color-line-strong);
}

.pm-picker:focus-within {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* overflow: a select narrower than its option text (large text on a phone) already cuts the text off;
   without it WebKit still counts the hidden text as page width and scrolls sideways (decision 0090). */
.pm-picker select {
    min-width: 0;
    max-width: 100%;
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--color-text);
    padding: 0;
    overflow: hidden;
}

.pm-picker select:focus-visible {
    outline: none;
}

.pm-picker-chevron {
    width: var(--icon-size-small);
    height: var(--icon-size-small);
    flex: 0 0 auto;
    color: var(--color-text-muted);
    pointer-events: none;
}

.pm-picker-create {
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
}

.pm-picker-create[hidden] {
    display: none;
}

.pm-picker-create .pm-input {
    min-width: var(--field-min-width);
    width: auto;
}

/* The project picker's create row fills the pickers' width inside the Timer. */
.pm-timer-filters .pm-picker-create {
    width: 100%;
}

.pm-timer-filters .pm-picker-create .pm-input {
    flex: 1 1 auto;
    min-width: 0;
}

/* The activity and task pickers' one text field takes the select's place at the same width
   and height (decision 0070). */
.pm-picker-field > [data-inline-input] {
    width: 100%;
    min-height: var(--timer-chip-height);
}

.pm-picker-field > [data-inline-input][hidden],
.pm-time-field > [data-inline-input][hidden] {
    display: none;
}

.pm-time-field > [data-inline-input] {
    width: 100%;
}

/* The typed-name field reads like the select it replaces, so its placeholder has the
   colour of the select's disabled hint (B-11). */
[data-inline-input]::placeholder {
    color: var(--color-text-muted);
}

/* Suggestions of existing activities appear while typing; the field shows no drop-down arrow. */
[data-inline-input]::-webkit-calendar-picker-indicator {
    display: none !important;
}

/* Inside the Timer the panel fills the pickers' width, so its row ends on the same
   right edge as the pickers above it (decision 0069). */
.pm-timer-filters .pm-picker-create {
    width: 100%;
}

.pm-timer-filters .pm-picker-create .pm-input,
.pm-timer-filters .pm-picker-create .pm-select-wrap {
    flex: 1 1 auto;
    min-width: 0;
}

.pm-time-field .pm-picker-create {
    display: flex;
    width: 100%;
}

.pm-time-field .pm-picker-create[hidden] {
    display: none;
}

.pm-time-field .pm-picker-create .pm-input,
.pm-time-field .pm-picker-create .pm-select-wrap {
    flex: 1 1 auto;
    min-width: 0;
}

.pm-tag .pm-accent-text {
    color: var(--color-accent);
    font-weight: var(--weight-medium);
}

/* No-JavaScript fallbacks: expose menu actions as static controls */
html:not(.js) .pm-menu-wrap {
    display: block;
}

html:not(.js) .pm-menu[hidden] {
    position: static;
    display: block;
    min-width: 0;
    margin-top: var(--space-2);
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}

html:not(.js) .pm-row-actions {
    opacity: 1;
}

html:not(.js) .pm-inline-edit[hidden] {
    display: block;
}

@media (max-width: 47.999em) {
    .pm-module-line {
        grid-template-columns: minmax(0, 1fr);
        /* Stacked modules keep the same vertical gap as module lines (B-10 review). */
        row-gap: var(--module-gap);
    }

    /* Full-width stacked pickers on phones (B-10 review). */
    .pm-timer-filters .pm-picker-field {
        flex: 1 1 100%;
    }
}

@media (max-width: 47.999em) {
    .pm-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .pm-filters {
        width: 100%;
    }

    .pm-field {
        flex: 1 1 var(--field-mobile-basis);
    }

    .pm-field.search,
    .pm-search {
        min-width: 100%;
    }

    .pm-row {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--row-gap-compact);
    }

    .pm-row-meta {
        justify-content: flex-start;
        flex-wrap: wrap;
    }

    .pm-row-actions {
        position: static;
        transform: none;
        padding-inline-start: 0;
        background: transparent;
        opacity: 1;
        pointer-events: auto;
    }

    /* B-27: the to-do checkbox and the "Show completed" summary reach the narrow-screen
       control height. The checkbox keeps its drawn size and layout: the box grows and
       a negative margin gives the extra back, so only the touch area changes. */
    .pm-row .pm-check,
    .pm-row .pm-todo-check {
        min-width: var(--control-height);
        min-height: var(--control-height);
        justify-content: center;
        margin: calc((var(--check-size) - var(--control-height)) / 2);
    }

    .pm-today-completed summary,
    .pm-todo-completed summary {
        min-height: var(--control-height);
    }

    /* Phone touch targets grow to the narrow-screen control height (checklist 21). */
    .pm-picker,
    .pm-picker-field > [data-inline-input] {
        min-height: var(--control-height);
    }

    .pm-subnav {
        position: static;
        display: flex;
        flex-wrap: wrap;
    }

    .pm-subnav-link {
        flex: 0 0 auto;
    }
}

@media (max-width: 27.499em) {
    .pm-panel {
        padding: var(--panel-pad-compact);
    }
}

/* List tables (decision 0057, design docs/design/references/promemio-lists-v1.html).
   A list whose rows hold several values shares one grid between a visual header
   row and its rows, so every value sits under its label. Pages define the grid
   (.pm-cols-*) and fold columns with container queries on .pm-table. The header
   is visual only; rows keep list semantics and their own accessible text. */
.pm-table { min-width: 0; container: pm-list / inline-size; }
.pm-table-head {
    min-height: var(--control-height-compact);
    padding: 0 var(--row-pad-inline);
    margin: var(--space-2) 0 0;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}
.pm-table-head > span { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.pm-table .pm-row > * { min-width: 0; }
.pm-table .pm-row:hover { background: var(--color-hover); }
.pm-table .pm-row.danger:hover { background: var(--color-danger-bg); }
.pm-cell-text { display: block; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.pm-cell-empty { color: var(--color-text-disabled); }
.pm-cell-stack { display: none; flex-wrap: wrap; gap: 0 var(--space-3); color: var(--color-text-muted); font-size: var(--text-sm); overflow-wrap: anywhere; }
.pm-col-date, .pm-col-clock, .pm-col-duration { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pm-col-duration { text-align: right; }
.pm-col-actions { display: flex; justify-content: flex-end; gap: var(--space-1); }
/* Inside a column the row actions are an ordinary cell, still shown on hover/focus. */
.pm-col-actions .pm-row-actions { position: static; transform: none; padding-inline-start: 0; background: transparent; }

/* Forgotten-timer notice (decision 0062) */
.pm-active-timer.is-long { border-color: var(--color-danger); color: var(--color-danger); }
.pm-active-timer.is-long .pm-icon { color: var(--color-danger); }
.pm-long-timer {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-3) var(--space-5);
    margin-bottom: var(--space-5);
    padding: var(--space-4);
    border: 1px solid var(--color-danger);
    border-radius: var(--radius-card);
    background: var(--color-danger-bg);
}
.pm-long-timer[hidden] { display: none; }
.pm-long-timer-copy { min-width: 0; flex: 1 1 18rem; display: flex; align-items: flex-start; gap: var(--space-3); }
.pm-long-timer-copy > .pm-icon { flex: none; width: var(--icon-size); height: var(--icon-size); margin-top: var(--space-1); color: var(--color-danger); }
.pm-long-timer h2 { margin: 0; font-size: var(--text-md); font-weight: var(--weight-medium); line-height: var(--line-height-title-md); }
.pm-long-timer p { margin: var(--space-1) 0 0; color: var(--color-text-muted); overflow-wrap: anywhere; }
.pm-long-timer-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2); margin: 0; }
.pm-long-timer-field { display: grid; gap: var(--space-1); min-width: 0; color: var(--color-text-muted); font-size: var(--text-sm); }
.pm-long-timer-field .pm-input { min-width: 0; }
.pm-long-timer-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pm-long-timer-actions form { margin: 0; }

/* A picker with no project chosen is disabled; its text is the hint to choose a
   project first, so it keeps the muted text colour that meets contrast (decision 0069). */
.pm-picker select:disabled {
    color: var(--color-text-muted);
}

/* Plan editor dialog (screen F): shared by Calendar and Today's Add calendar block. */
.pm-calendar-form,
.pm-calendar-repeat-grid,
.pm-calendar-times {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
    min-width: 0;
}
.pm-calendar-repeat-grid, .pm-calendar-times { gap: var(--space-3); }
.pm-calendar-form .span-2, .pm-calendar-repeat-grid .span-2 { grid-column: 1 / -1; }
.pm-calendar-field { display: grid; align-content: start; min-width: 0; margin: 0; padding: 0; border: 0; }
.pm-calendar-field[hidden], .pm-calendar-form [hidden] { display: none; }
.pm-calendar-form .pm-field-help, .pm-calendar-form .pm-field-error { margin: 0; }
.pm-calendar-field > .pm-field-error { margin-top: var(--space-1); }
.pm-calendar-form .pm-textarea { min-height: calc(2 * var(--control-height)); }
.pm-calendar-repeat {
    min-width: 0;
    margin: 0;
    padding: var(--space-3);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-control);
}
.pm-calendar-repeat > legend { padding: 0 var(--space-2); font-weight: var(--weight-medium); }
.pm-calendar-weekdays > legend { padding: 0; }
.pm-calendar-weekday-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--space-1); min-width: 0; }
.pm-calendar-weekday {
    position: relative;
    display: grid;
    place-items: center;
    min-height: var(--control-height-compact);
    border: 1px solid var(--color-line-control);
    border-radius: var(--radius-control);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
}
.pm-calendar-weekday input { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; }
.pm-calendar-weekday:has(input:checked) {
    border-color: var(--color-accent);
    background: var(--color-accent);
    color: var(--color-on-accent);
    font-weight: var(--weight-medium);
}
.pm-calendar-weekday:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.pm-calendar-dialog-buttons { display: inline-flex; flex-wrap: wrap; gap: var(--space-2); margin-inline-start: auto; }
@media (max-width: 47.999em) {
    .pm-calendar-form, .pm-calendar-repeat-grid { grid-template-columns: minmax(0, 1fr); }
    .pm-calendar-form .span-2, .pm-calendar-repeat-grid .span-2 { grid-column: auto; }
    .pm-calendar-weekday { min-height: var(--control-height); }
    .pm-calendar-repeat { padding: var(--space-2); }
}

/* Time chart: bars per day, week or month. Shared by Reports, the project report and Today's This week (decisions 0058, 0059, B-07). */
.pm-report-chart { margin-top: var(--space-6); }
.pm-report-chart-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2) var(--space-4); margin-bottom: var(--space-3); }
.pm-report-chart-head h2 { margin: 0; font-size: var(--text-md); font-weight: var(--weight-medium); line-height: var(--line-height-title-md); }
.pm-report-chart-head span { color: var(--color-text-muted); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.pm-report-plot { position: relative; min-width: 0; container: report-plot / inline-size; }
.pm-report-bars {
    display: grid;
    grid-template-columns: repeat(var(--report-bars), minmax(0, 1fr));
    gap: var(--report-bar-gap);
    height: var(--report-chart-height);
    margin: 0;
    padding: 0;
    list-style: none;
    border-bottom: 1px solid var(--color-line);
}
.pm-report-bar { position: relative; min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; }
.pm-report-bar-hit {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    border-radius: var(--radius-small) var(--radius-small) 0 0;
    color: inherit;
}
a.pm-report-bar-hit:hover { background: var(--color-hover); }
a.pm-report-bar-hit:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.pm-report-bar-fill {
    width: min(100%, var(--report-bar-max));
    height: var(--report-value);
    min-height: 2px;
    border-radius: var(--radius-small) var(--radius-small) 0 0;
    background: var(--color-accent);
}
.pm-report-bar.is-offday .pm-report-bar-hit { background: color-mix(in srgb, var(--color-subtle) 45%, transparent); }
.pm-report-bar.is-offday a.pm-report-bar-hit:hover { background: var(--color-hover); }
.pm-report-bar-label {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    padding-top: var(--space-1);
    overflow: hidden;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    text-align: center;
    white-space: nowrap;
}
.pm-report-bar.is-today .pm-report-bar-label { color: var(--color-accent); font-weight: var(--weight-medium); }
.pm-report-plot { padding-bottom: calc(var(--text-xs) * 1.6 + var(--space-1)); }
.pm-report-average {
    position: absolute;
    z-index: 1;
    inset-inline: 0;
    bottom: calc(var(--text-xs) * 1.6 + var(--space-1) + var(--report-chart-height) * var(--report-average) / 100);
    border-top: 1px dashed var(--color-line-strong);
    pointer-events: none;
}
.pm-report-average span {
    position: absolute;
    inset-inline-end: 0;
    bottom: var(--space-1);
    padding-inline: var(--space-1);
    border-radius: var(--radius-small);
    background: var(--color-bg);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
}
.pm-report-average.is-near-top span { top: var(--space-1); bottom: auto; }


/* Bar labels: long labels (Mon 21) only when there is room; narrow plots show
   the short label and only every fifth day of a month. */
.pm-report-bar-label .is-short { display: none; }
@container report-plot (max-width: 36rem) {
    .pm-report-bar-label .is-long { display: none; }
    .pm-report-bar-label .is-short { display: inline; }
    .pm-report-bars--day[data-report-dense] .pm-report-bar:not(:nth-child(5n + 1)):not(.is-today) .pm-report-bar-label { visibility: hidden; }
}
/* Weekday labels (option labels=weekday): "Mon 28" while the plot is wide enough, then "M 28", then the day number alone. */
.pm-report-chart--weekday .pm-report-bar-label .is-long { display: inline; }
.pm-report-chart--weekday .pm-report-bar-label .is-letter,
.pm-report-chart--weekday .pm-report-bar-label .is-short { display: none; }
@container report-plot (max-width: 21rem) {
    .pm-report-chart--weekday .pm-report-bar-label .is-long { display: none; }
    .pm-report-chart--weekday .pm-report-bar-label .is-letter { display: inline; }
}
@container report-plot (max-width: 14rem) {
    .pm-report-chart--weekday .pm-report-bar-label .is-letter { display: none; }
    .pm-report-chart--weekday .pm-report-bar-label .is-short { display: inline; }
}
/* Values (option values): the duration sits above its bar; the plot reserves one line for the tallest bar. */
.pm-report-chart--values .pm-report-plot { padding-top: calc(var(--text-xs) * 1.6 + var(--space-1)); }
.pm-report-chart--values .pm-report-bar-fill { position: relative; }
.pm-report-bar-value {
    position: absolute;
    inset-inline-start: 50%;
    bottom: 100%;
    transform: translateX(-50%);
    padding-bottom: var(--space-1);
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    line-height: 1.6;
    white-space: nowrap;
}
@container report-plot (max-width: 16rem) {
    .pm-report-bar-value { display: none; }
}
/* Weeks of a long range: the month name sits on the first week of each month and may run past its bar. */
.pm-report-bar.is-month-start .pm-report-bar-label { overflow: visible; text-align: left; }

/* Breakdown list with a bar per row. Shared by Reports, the project report and the Today time modules (decisions 0058, 0059, 0079). */

.pm-report-breakdown { min-width: 0; container: report-breakdown / inline-size; }
.pm-report-breakdown h2 { margin: 0 0 var(--space-2); font-size: var(--text-md); font-weight: var(--weight-medium); line-height: var(--line-height-title-md); }
.pm-report-bar-list { margin: 0; padding: 0; list-style: none; }
.pm-report-bar-row {
    display: grid;
    grid-template-columns: minmax(0, var(--report-name-col)) minmax(var(--space-7), 1fr) var(--list-col-duration) var(--report-percent-col);
    align-items: center;
    gap: var(--space-3);
    min-height: var(--control-height);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--color-line);
}
.pm-report-bar-name { min-width: 0; display: flex; align-items: center; gap: var(--space-2); color: var(--color-text); text-decoration: none; }
.pm-report-bar-name:hover { text-decoration: underline; }
.pm-report-bar-name .pm-dot { flex: none; }
.pm-report-track { height: var(--report-track-height); overflow: hidden; border-radius: 999px; background: var(--color-line); }
.pm-report-fill { display: block; height: 100%; border-radius: inherit; background: var(--color-accent); }
.pm-report-bar-row strong { font-weight: var(--weight-medium); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.pm-report-percent { color: var(--color-text-muted); font-size: var(--text-sm); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
@container report-breakdown (max-width: 30rem) {
    /* Name, time and share share the first line; the bar takes the line under it. */
    .pm-report-bar-row {
        grid-template-columns: minmax(0, 1fr) var(--list-col-duration) var(--report-percent-col);
        gap: var(--space-2) var(--space-3);
    }
    .pm-report-bar-name { grid-column: 1; grid-row: 1; align-items: flex-start; }
    .pm-report-bar-name .pm-dot { margin-top: calc((1lh - var(--dot-size)) / 2); }
    .pm-report-bar-name .pm-cell-text { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
    .pm-report-track { grid-column: 1 / -1; grid-row: 2; }
    .pm-report-bar-row > strong { grid-column: 2; grid-row: 1; }
    .pm-report-percent { grid-column: 3; grid-row: 1; }
}
/* Very narrow lists (a phone at large text sizes): the name keeps its own full line, time and share sit under the bar. */
@container report-breakdown (max-width: 15rem) {
    .pm-report-bar-row { grid-template-columns: minmax(0, 1fr) auto; }
    .pm-report-bar-name { grid-column: 1 / -1; }
    .pm-report-bar-row > strong { grid-column: 1; grid-row: 3; text-align: left; }
    .pm-report-percent { grid-column: 2; grid-row: 3; }
}
/* Names that wrap (the Today time modules): the dot stays on the first line. */
.pm-report-breakdown.is-wrap .pm-report-bar-name { align-items: flex-start; }
.pm-report-breakdown.is-wrap .pm-report-bar-name .pm-dot { margin-top: calc((1lh - var(--dot-size)) / 2); }
.pm-report-breakdown.is-wrap .pm-report-bar-name .pm-cell-text { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }
