      :root {
  --tk-blue-950: #0B1120;
  --tk-blue-900: #10182A;
  --tk-blue-800: #18233A;
  --tk-blue-700: #202D48;
  --tk-blue-600: #2A3A58;
  --tk-blue-500: #3A506F;
  --tk-blue-400: #587291;
  --tk-blue-accent: #65B6DE;
  --tk-gallery-canvas: #E7EBF0;
  --tk-gallery-surface: #EDF0F3;
  --tk-gallery-ink: #18233A;
  --tk-gallery-muted: #56647A;
  --tk-gallery-line: rgba(24, 35, 58, 0.2);
  --tk-modal-backdrop: rgba(218, 228, 241, 0.62);
  --tk-parchment: #C5A57C;
  --tk-parchment-deep: #B28D63;
  --tk-tan-soft: #E4D5C1;

  --tk-brown-900: #2A1B12;
  --tk-brown-800: #3B271B;
  --tk-brown-700: #4A3425;
  --tk-brown-600: #5B3D2D;
  --tk-brown-500: #6A4B37;
  --tk-brown-400: #7A5540;
  --tk-brown-300: #8B6A52;
  --tk-brown-200: #8F674F;
  --tk-brown-muted: #866C5A;

  /* Universal application surfaces: the Archive Explorer palette is the standard. */
  --tk-bg: var(--tk-gallery-canvas);
  --tk-bg-soft: var(--tk-gallery-surface);
  --tk-bg-panel: var(--tk-gallery-canvas);
  --tk-bg-card: var(--tk-gallery-surface);
  --tk-hover-fill: rgba(197, 165, 124, 0.18);
  --tk-surface-glass: rgba(16, 24, 42, 0.96);
  --tk-surface-translucent: rgba(24, 35, 58, 0.9);

  --tk-text: var(--tk-gallery-ink);
  --tk-text-secondary: #35445C;
  --tk-text-muted: var(--tk-gallery-muted);
  --tk-text-inverse: #F7EFE3;

  --page: var(--tk-bg);
  --bg: var(--tk-bg);
  --paper: var(--tk-bg-panel);
  --paper-strong: var(--tk-bg-card);
  --ink: var(--tk-text);
  --muted: var(--tk-text-muted);
  --accent: var(--tk-parchment-deep);
  --accent-deep: var(--tk-gallery-ink);
  --accent-soft: rgba(197, 165, 124, 0.2);
  --line: var(--tk-gallery-line);
  --line-soft: rgba(24, 35, 58, 0.1);
  --danger: #7B2E22;
  --warning: #8A5A28;
  --gold: #D8AD79;
  --selected: var(--tk-parchment);
  --glass: rgba(231, 235, 240, 0.96);
  --hero: linear-gradient(135deg, #0B1120 0%, #10182A 48%, #202D48 100%);
  --shadow: 0 18px 45px rgba(24, 35, 58, 0.14);

  --blue: var(--tk-blue-accent);
  --green: #83B79A;
  --red: var(--danger);
}

      /* THE HEIGHT OF THE BAR, AS A NUMBER EVERY PAGE CAN READ. Five pages size themselves as
         "the screen minus the header", and before this they each guessed: three wrote `48px`
         outright, `jobs.html` and `customer_approvals.html` read a `--tk-header-height` that
         nothing defined and fell back to 48px, and `admin.html` fell back to 58px. Three
         different answers to one question, none of them wrong until the bar moved.

         Declared on :root rather than on `.site-nav`, because the pages that need it are not
         inside the bar. */
      :root {
        --tk-header-height: 160px;
      }

      .site-nav {
        --tk-nav-rail-width: 340px;
        --tk-bg: var(--tk-blue-950);
        --tk-bg-soft: var(--tk-blue-900);
        --tk-bg-panel: var(--tk-blue-800);
        --tk-bg-card: var(--tk-blue-700);
        --tk-hover-fill: var(--tk-blue-600);
        --tk-text: #F4EBDD;
        --tk-text-muted: #A9B1C2;
        --ink: var(--tk-text);
        --muted: var(--tk-text-muted);
        --line: rgba(218, 228, 241, 0.16);
        --accent: #B9825E;
        --accent-deep: #D5A878;
        --danger: #E38A80;
        border-bottom: 1px solid var(--line);
        background: var(--tk-surface-glass);
        box-shadow: 0 8px 24px rgba(2, 7, 18, 0.24);
        position: relative;
        z-index: 60;
        height: var(--tk-header-height);
        min-height: var(--tk-header-height);
        overflow: visible;
      }

      .site-nav::after {
        content: none;
      }

      /* Long form workspaces keep the full medallion inside the header instead
         of letting it overlap the scrolling page content. */
      /* Long form workspaces keep the header pinned while the page scrolls. That is all this
         class does now: the medallion it used to enlarge is the same size on every page, so the
         reserved rail, the absolute positioning and the second bar height have all gone. */
      .medallion-header-page > .site-nav {
        position: sticky;
        top: 0;
      }

      /* Keep page content flush with the navigation; do not expose a canvas-colored band below it. */
      body > .site-nav + :is(main, .shell, .page, .portal-shell, .landing-main) {
        margin-top: 0 !important;
        padding-top: 0 !important;
      }

      .nav-inner,
      .footer-inner {
        max-width: 1500px;
        margin: 0 auto;
        padding: 12px 22px;
      }

      .nav-inner {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: 8px;
        width: 100%;
        /* The ROW follows the bar. Pinned at 48px it stayed 48px while the bar grew, and the
           medallion -- centred in a row shorter than itself -- hung 44px above the top of the
           header and over the page behind it. */
        height: var(--tk-header-height);
        max-width: none;
        margin: 0;
        padding: 5px 12px;
        z-index: 1;
      }

      .brand {
        display: inline-flex;
        align-items: center;
        gap: 14px;
        min-width: 220px;
        color: var(--ink);
        text-decoration: none;
      }

      .brand img {
        display: block;
        width: 156px;
        max-width: 40vw;
        border-radius: 10px;
      }

      .brand-name {
        display: grid;
        gap: 1px;
        line-height: 1;
      }

      .brand-name strong {
        color: var(--ink);
        font-size: 1.12rem;
        font-weight: 900;
      }

      .brand-name span {
        color: var(--muted);
        font-size: 0.78rem;
        font-weight: 700;
      }

      .task-node-wrap {
        /* An ordinary item in the row, so it takes the row's own left padding and the row's gap
           rather than an offset plus a reserved rail kept in step with its size -- which is what
           left it 8px inboard of the content edge with a 32px void after it.
           Relative, not static: the task popover is positioned against this element. */
        position: relative;
        z-index: 100;
        flex: 0 0 auto;
      }

      .task-node {
        --task-progress: 0%;
        position: relative;
        width: var(--tk-medallion-size, 44px);
        height: var(--tk-medallion-size, 44px);
        display: grid;
        place-items: center;
        border: 0;
        border-radius: 50%;
        padding: 10px;
        background: transparent;
        cursor: pointer;
      }

      .task-node-art {
        position: relative;
        z-index: 2;
        /* SIZED BY THE BUTTON, NEVER BESIDE IT. This was 36px, with a second hand-tuned 116px for
           the large header and a third 38px for phones -- three numbers that each agreed with the
           button at one size only. At 44px the art was LARGER than the button's 24px content box,
           and an overflowing grid item is aligned to start rather than centred (the browser's
           overflow-alignment rule, which exists so content cannot vanish off the top-left). So the
           logo sat 6px down and right of the ring drawn around it, which is the misalignment
           visible on every ordinary page. Filling the content box cannot disagree at any size. */
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        overflow: hidden;
        border: 2px solid rgba(216, 188, 151, 0.54);
        border-radius: 50%;
        background: var(--tk-bg-soft);
        box-shadow: 0 6px 16px rgba(2, 7, 18, 0.38);
      }

      .task-node-art img {
        width: 100%;
        height: 100%;
        display: block;
        object-fit: cover;
        object-position: center;
        filter: sepia(0.14) saturate(0.92) brightness(1.08);
        transform: scale(1.7);
      }

      .task-node-orbit {
        position: absolute;
        inset: 0;
        z-index: 1;
        border-radius: 50%;
        opacity: 0;
        background: conic-gradient(#57baf0 0 var(--task-progress), transparent var(--task-progress) 100%);
        filter: drop-shadow(0 0 5px rgba(61, 174, 234, 0.9));
        transition: opacity 160ms ease;
      }

      .task-node-orbit::after {
        content: "";
        position: absolute;
        inset: 8px;
        border-radius: 50%;
        background: var(--tk-bg);
      }

      .task-node.active .task-node-orbit { opacity: 1; }
      .task-node.indeterminate .task-node-orbit {
        background: conic-gradient(from 0deg, transparent 0 70%, #71c7f4 86%, #2f98cf 94%, transparent 100%);
        animation: task-orbit-spin 1.15s linear infinite;
      }

      @keyframes task-orbit-spin { to { transform: rotate(360deg); } }

      .task-node:focus-visible {
        outline: 3px solid rgba(73, 157, 203, 0.5);
        outline-offset: 2px;
      }

      .task-node-count {
        position: absolute;
        right: -2px;
        top: -1px;
        z-index: 3;
        min-width: 18px;
        height: 18px;
        display: grid;
        place-items: center;
        border: 2px solid var(--tk-bg);
        border-radius: 999px;
        padding: 0 4px;
        background: #238cc5;
        color: #fff;
        font-size: 0.68rem;
        font-weight: 900;
      }

      .task-node-count[hidden] { display: none; }

      .task-node-popover {
        position: absolute;
        left: 0;
        /* Hung off the medallion, not off a number. 60px was 44 + a gap, and 142px was a second
           copy of the same sum for the large header; both went stale the moment the medallion
           moved. */
        top: calc(var(--tk-medallion-size) + 6px);
        z-index: 110;
        width: min(430px, calc(100vw - 28px));
        max-height: min(620px, calc(100dvh - 100px));
        display: none;
        grid-template-rows: auto minmax(0, 1fr) auto;
        overflow: hidden;
        border: 1px solid var(--line);
        border-radius: 10px;
        background: var(--tk-bg-soft);
        color: var(--tk-text-inverse);
        box-shadow: 0 22px 55px rgba(2, 7, 18, 0.48);
      }

      /* The medallion is 136px against a 48px bar, so it overhung by ~88px onto whatever the
         page put beneath -- on most pages its own first heading. It is sized to the bar by
         default and only grows on a page that has actually reserved the height, which today is
         upload.html and archive_import.html. Making another page roomy is one class on its
         <body>, not a measurement guessed at runtime.
         Behaviour is untouched either way: hover opens the task popover on a pointer, and a tap
         opens it on a touch screen, which is the only way in on a phone. */
      /* Only a page that reserves header height overhangs, and only an overhang has to be lifted
         out of the row and centred in a rail of its own. */
      /* Without the overhang the nav has no reason to start 340px in. */
      /* This palette is light-only -- there is no dark set of tokens behind it. Saying so stops
         a browser deciding for itself: an undeclared page is fair game for Chrome's automatic
         darkening, which inverts backgrounds without inverting every colour that sits on them
         and leaves dark text on a now-dark surface. Declaring the scheme also fixes form
         controls and scrollbars, which otherwise render dark on a dark OS against light panels.
         This is a statement of what exists, not a preference: if dark mode is wanted it needs a
         real second set of tokens, and then this becomes `light dark`. */
      :root {
        color-scheme: only light;
      }

      /* A page whose content area is sized to the viewport has to subtract this as well as the
         header, or the footer is pushed off the bottom by exactly its own height and the page
         gains a sliver of scroll that looks like a bug. */
      body {
        --tk-footer-height: 56px;
      }

      .site-nav {
        --tk-nav-rail-width: 0px;
        /* The full medallion on every page, not just Upload and Archive Import. It stays a normal
           item in the header row -- it is not lifted out and floated over the page -- so the row
           reserves its width and nothing can be covered by it. The bar grows to hold it, and
           `--tk-header-height` is what tells the rest of the site by how much. */
        --tk-medallion-size: 136px;
      }

      .task-node-popover.open { display: grid; }

      .timekeeper-busy-overlay {
        position: fixed;
        inset: 0;
        z-index: 10000;
        display: grid;
        place-content: center;
        justify-items: center;
        gap: 16px;
        background: rgba(4, 15, 31, 0.28);
        backdrop-filter: blur(2px);
        cursor: wait;
      }

      .timekeeper-busy-overlay[hidden] { display: none; }

      .timekeeper-busy-indicator {
        position: relative;
        width: 150px;
        height: 150px;
        display: grid;
        place-items: center;
      }

      .timekeeper-busy-art {
        position: relative;
        z-index: 2;
        width: 126px;
        height: 126px;
        overflow: hidden;
        border: 2px solid rgba(216, 188, 151, 0.7);
        border-radius: 50%;
        background: var(--tk-bg-soft);
        box-shadow: 0 12px 34px rgba(2, 7, 18, 0.48);
      }

      .timekeeper-busy-art img {
        width: 100%;
        height: 100%;
        display: block;
        object-fit: cover;
        object-position: center;
        filter: sepia(0.14) saturate(0.92) brightness(1.08);
        transform: scale(1.7);
      }

      .timekeeper-busy-orbit {
        position: absolute;
        inset: 0;
        z-index: 1;
        border-radius: 50%;
        background: conic-gradient(from 0deg, transparent 0 70%, #71c7f4 86%, #2f98cf 94%, transparent 100%);
        filter: drop-shadow(0 0 8px rgba(61, 174, 234, 0.95));
        animation: task-orbit-spin 1.05s linear infinite;
      }

      .timekeeper-busy-orbit::after {
        content: "";
        position: absolute;
        inset: 9px;
        border-radius: 50%;
        background: var(--tk-bg);
      }

      .timekeeper-busy-overlay strong {
        border: 1px solid rgba(216, 188, 151, 0.54);
        border-radius: 999px;
        padding: 9px 16px;
        background: var(--tk-bg-soft);
        color: var(--tk-text);
        box-shadow: 0 8px 24px rgba(2, 7, 18, 0.3);
        font-size: 1rem;
      }
      .task-popover-header,
      .task-popover-footer { padding: 13px 14px; }
      .task-popover-header {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: 12px;
        border-bottom: 1px solid var(--line);
      }
      .task-popover-header > div { display: grid; gap: 2px; }
      .task-popover-header strong {
        color: var(--tk-text-inverse);
        font: 800 1.05rem/1.1 "Source Serif Pro", Georgia, serif;
      }
      .task-popover-header span { color: var(--muted); font-size: 0.8rem; }
      .task-popover-close {
        border: 0; padding: 0 3px; background: transparent; color: var(--muted);
        font-size: 1.35rem; cursor: pointer;
      }
      .task-popover-body { min-height: 80px; overflow: auto; padding: 8px 14px; }
      .task-empty { margin: 18px 0; color: var(--muted); text-align: center; }
      .task-card { position: relative; display: grid; gap: 7px; padding: 11px 0; border-bottom: 1px solid var(--line); }
      .task-card:last-child { border-bottom: 0; }
      .task-card-heading,
      .task-card-meta { display: flex; justify-content: space-between; gap: 12px; }
      .task-card-heading strong { color: var(--tk-text-inverse); }
      .task-card-heading span { color: var(--tk-blue-accent); font-size: 0.76rem; font-weight: 900; }
      .task-card-meta,
      .task-card small { color: var(--muted); font-size: 0.78rem; }
      .task-card small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      .task-card-progress { height: 5px; overflow: hidden; border-radius: 999px; background: rgba(218, 228, 241, 0.1); }
      .task-card-progress span { display: block; width: var(--progress); height: 100%; background: #49aade; }
      .task-cancel { justify-self: end; border: 0; background: transparent; color: var(--danger); font-weight: 800; cursor: pointer; }
      .task-popover-footer { display: flex; justify-content: flex-end; border-top: 1px solid var(--line); }
      .task-popover-footer .button { min-height: 36px; padding: 8px 12px; border-radius: 7px; text-decoration: none; font-weight: 850; }

      .nav-menu,
      .footer-inner,
      .footer-inner div,
      .footer-inner nav {
        display: flex;
        align-items: center;
        gap: 12px;
      }

      /* A new element, so desktop rendering is unchanged: it is simply not there until the
         phone breakpoint reveals it. */
      /* A short page used to leave the footer stranded in the middle of the window with dead
         space beneath it, at every width. Making the body a flex column and giving the footer
         `margin-top: auto` is the usual fix and was measured to move unrelated content on three
         pages -- body's layout model is load-bearing here. Sticky does the same job without
         touching it: the page is merely made viewport-tall, and the footer sticks to the bottom
         of the viewport until the content is long enough to push it further down.
         This is the one rule here that is deliberately not phone-only. */
      body {
        min-height: 100dvh;
      }

      .site-footer {
        position: sticky;
        /* 100vh, not 100dvh, and measured rather than chosen: with `top: 100dvh` against a
           body of `min-height: 100dvh`, Chrome sized an ancestor of scanned_items.html by
           max-content and its 720px table pushed the page to 750px on a 344px phone. The
           dynamic unit buys nothing for a footer offset -- it only has to mean "one viewport
           down" -- so the static one is used. Do not "modernise" this to dvh. */
        top: 100vh;
      }

      .nav-menu-toggle,
      .nav-sheet-head {
        display: none;
      }

      .nav-menu {
        flex: 1 1 auto;
        flex-wrap: nowrap;
        justify-content: flex-start;
        gap: 7px;
        margin-left: var(--tk-nav-rail-width);
        min-width: 0;
        color: var(--muted);
        font-weight: 800;
      }

      .nav-menu-group {
        position: relative;
      }

      .nav-menu-trigger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        min-height: 32px;
        border: 1px solid var(--line);
        border-radius: 7px;
        padding: 6px 9px;
        background: var(--tk-bg-panel);
        color: var(--ink);
        font-size: 0.82rem;
        font-weight: 850;
        line-height: 1;
        text-decoration: none;
        cursor: pointer;
      }

      .nav-menu-trigger:hover,
      .nav-menu-group:hover > .nav-menu-trigger,
      .nav-menu-group.open > .nav-menu-trigger {
        border-color: var(--accent);
        background: var(--tk-hover-fill);
        color: var(--tk-text);
      }

      .nav-menu-trigger.active {
        border-color: var(--tk-parchment-deep);
        background: var(--tk-parchment);
        color: var(--tk-gallery-ink);
      }

      .nav-caret {
        width: 0;
        height: 0;
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        border-top: 5px solid currentColor;
      }

      .nav-dropdown {
        position: absolute;
        top: calc(100% + 8px);
        left: 0;
        z-index: 80;
        min-width: 210px;
        display: grid;
        gap: 4px;
        padding: 8px;
        border: 1px solid var(--line);
        border-radius: 8px;
        background: var(--tk-bg-soft);
        box-shadow: 0 18px 44px rgba(42, 27, 18, 0.2);
        box-sizing: border-box;
        overflow: hidden;
        opacity: 0;
        pointer-events: none;
        transform: translateY(-4px);
        transition: opacity 110ms ease, transform 110ms ease;
      }

      .nav-menu > :last-child .nav-dropdown {
        right: 0;
        left: auto;
      }

      .nav-dropdown::before {
        content: "";
        position: absolute;
        inset: -10px 0 auto 0;
        height: 10px;
      }

      .nav-menu-group.open > .nav-dropdown {
        opacity: 1;
        pointer-events: auto;
        transform: translateY(0);
      }

      .nav-dropdown-item,
      .nav-dropdown-label {
        box-sizing: border-box;
        width: 100%;
        display: flex;
        align-items: center;
        min-height: 36px;
        border: 0;
        border-radius: 6px;
        padding: 8px 10px;
        background: transparent;
        color: var(--ink);
        font: inherit;
        font-size: 0.9rem;
        font-weight: 850;
        text-align: left;
        text-decoration: none;
        white-space: nowrap;
      }

      .nav-dropdown-item {
        cursor: pointer;
      }

      .nav-dropdown-item:hover,
      .nav-dropdown-item:focus {
        outline: none;
        background: var(--tk-hover-fill);
        color: var(--tk-text);
      }

      .nav-dropdown-item.active {
        outline: none;
        background: var(--tk-parchment);
        color: var(--tk-gallery-ink);
      }

      .nav-dropdown-item:disabled {
        opacity: 0.45;
        cursor: not-allowed;
      }

      .nav-dropdown-danger { color: var(--danger); }

      .nav-dropdown-separator {
        height: 1px;
        margin: 4px 6px;
        background: var(--line);
      }

      .nav-dropdown-label {
        color: var(--muted);
        cursor: default;
      }

      .archive-explorer-dropdown {
        width: max-content;
        min-width: 280px;
        max-width: min(620px, calc(100vw - 24px));
      }
      #archive-menu-list {
        width: max-content;
        min-width: 100%;
        max-width: 100%;
        max-height: min(520px, calc(100dvh - 90px));
        display: grid;
        gap: 4px;
        overflow-x: hidden;
        overflow-y: auto;
      }
      .archive-explorer-dropdown .nav-dropdown-item {
        width: 100%;
        max-width: 100%;
        white-space: normal;
        overflow-wrap: anywhere;
      }

      .nav-dropdown-form,
      .logout-form,
      .status-form {
        margin: 0;
      }

      .nav-dropdown-form {
        width: 100%;
      }

      button.primary,
      .button.primary {
        border-color: var(--tk-parchment-deep);
        background: var(--tk-parchment);
        color: var(--tk-gallery-ink);
      }

      button.primary:hover,
      .button.primary:hover,
      button.primary:focus-visible,
      .button.primary:focus-visible {
        border-color: var(--tk-parchment-deep);
        background: var(--tk-parchment-deep);
        color: var(--tk-gallery-ink);
      }

      input,
      select,
      textarea {
        border-color: var(--line);
        background: var(--tk-bg-soft);
        color: var(--tk-text);
      }

      input::placeholder,
      textarea::placeholder {
        color: var(--tk-text-muted);
      }

      .global-import-strip {
        border-top: 1px solid var(--line);
        background: rgba(217, 196, 173, 0.78);
      }

      .global-download-strip {
        background: rgba(234, 238, 232, 0.86);
      }

      .global-import-button {
        width: min(1500px, calc(100% - 44px));
        margin: 0 auto;
        display: grid;
        grid-template-columns: minmax(180px, auto) minmax(120px, 1fr) auto;
        gap: 12px;
        align-items: center;
        border: 0;
        padding: 9px 0;
        background: transparent;
        color: var(--ink);
        text-align: left;
        cursor: pointer;
      }

      .global-import-title,
      .global-import-percent {
        font-weight: 900;
        white-space: nowrap;
      }

      .global-import-phase {
        min-width: 0;
        overflow: hidden;
        color: var(--muted);
        font-size: 0.9rem;
        font-weight: 800;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .global-import-progress {
        height: 8px;
        min-width: 120px;
        overflow: hidden;
        border-radius: 999px;
        background: rgba(218, 228, 241, 0.12);
      }

      .global-import-progress span {
        display: block;
        width: var(--progress, 0%);
        height: 100%;
        border-radius: inherit;
        background: var(--accent);
      }

      .global-download-strip .global-import-progress span {
        background: #3f7f72;
      }

      .global-import-progress.indeterminate span {
        width: 42%;
        animation: archive-import-progress 1.15s ease-in-out infinite alternate;
      }

      @keyframes archive-import-progress {
        from {
          transform: translateX(-75%);
        }

        to {
          transform: translateX(150%);
        }
      }

      .global-import-modal-backdrop {
        position: fixed;
        inset: 0;
        z-index: 70;
        display: none;
        align-items: center;
        justify-content: center;
        padding: 22px;
        background: var(--tk-modal-backdrop);
      }

      .global-import-modal-backdrop.open {
        display: flex;
      }

      .global-import-modal {
        width: min(760px, 96vw);
        max-height: 88dvh;
        display: grid;
        grid-template-rows: auto minmax(0, 1fr) auto;
        overflow: hidden;
        border: 1px solid var(--line);
        border-radius: 8px;
        background: var(--paper, var(--tk-bg-panel));
        box-shadow: 0 28px 70px rgba(42, 27, 18, 0.24);
      }

      .global-import-modal header,
      .global-import-modal footer {
        padding: 16px;
        border-bottom: 1px solid var(--line);
      }

      .global-import-modal footer {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        justify-content: flex-end;
        border-top: 1px solid var(--line);
        border-bottom: 0;
      }

      .global-import-modal-body {
        min-height: 0;
        overflow: auto;
        padding: 16px;
      }

      .global-import-modal h2 {
        margin: 0;
        font-size: 1.4rem;
      }

      .global-import-modal .button {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 40px;
        border: 1px solid var(--line);
        border-radius: 7px;
        padding: 9px 14px;
        background: var(--tk-bg-soft);
        color: var(--ink);
        font: inherit;
        font-weight: 850;
        text-decoration: none;
        cursor: pointer;
      }

      .global-import-modal .button.primary {
        border-color: var(--tk-parchment-deep);
        background: var(--tk-parchment);
        color: var(--tk-gallery-ink);
      }

      .global-import-modal .button.danger {
        border-color: rgba(123, 46, 34, 0.38);
        color: var(--danger);
      }

      .global-import-stat-grid {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 10px;
        margin-top: 14px;
      }

      .global-import-stat {
        border: 1px solid var(--line);
        border-radius: 7px;
        padding: 11px;
        background: var(--tk-bg-soft);
        color: var(--muted);
        font-weight: 800;
      }

      .global-import-stat strong {
        display: block;
        margin-top: 4px;
        color: var(--ink);
        font-size: 1.2rem;
      }

      .global-import-detail-list {
        display: grid;
        gap: 8px;
        margin-top: 14px;
      }

      .global-import-detail-list div {
        display: grid;
        grid-template-columns: 140px minmax(0, 1fr);
        gap: 10px;
        border-bottom: 1px solid var(--line);
        padding-bottom: 8px;
      }

      .global-import-detail-list dt {
        color: var(--muted);
        font-weight: 850;
      }

      .global-import-detail-list dd {
        min-width: 0;
        margin: 0;
        overflow-wrap: anywhere;
      }

      .site-footer {
        --ink: #F4EBDD;
        --muted: #A9B1C2;
        --accent-deep: #D5A878;
        --line: rgba(218, 228, 241, 0.16);
        border-top: 1px solid var(--line);
        background: rgba(24, 35, 58, 0.92);
        color: var(--muted);
      }

      .footer-inner {
        justify-content: space-between;
        flex-wrap: wrap;
      }

      .footer-inner div,
      .footer-inner nav {
        flex-wrap: wrap;
      }

      .footer-inner a {
        color: var(--accent-deep);
        font-weight: 800;
        text-decoration: none;
      }

      /* Universal empty-result messaging sits directly on the current page canvas. */
      .empty,
      .empty-state {
        background: transparent !important;
        color: var(--tk-text-secondary, var(--ink)) !important;
      }

      @media (max-width: 980px) {

        .nav-inner {
          display: flex;
        }

        .nav-menu {
          justify-content: start;
          gap: 5px;
          margin-left: var(--tk-nav-rail-width);
        }


        .nav-menu-trigger { padding-inline: 7px; font-size: .76rem; }

        .global-import-button {
          width: calc(100% - 44px);
          grid-template-columns: 1fr auto;
        }

        .global-import-phase,
        .global-import-progress {
          grid-column: 1 / -1;
        }

        .global-import-stat-grid {
          grid-template-columns: repeat(2, minmax(0, 1fr));
        }
      }

      @media (max-width: 700px) {
        .task-node-popover { position: fixed; left: 14px; right: 14px; top: 62px; width: auto; max-height: calc(100dvh - 76px); }
        .brand {
          min-width: 0;
        }

        .brand img {
          width: 132px;
        }

        .brand-name {
          display: none;
        }

        /* A phone has no room for the rail the medallion sits in: 148px of reserved
           space plus a row of menus that cannot wrap is wider than the screen, so the
           last menus were pushed off it and the whole page scrolled sideways. The
           medallion shrinks to a badge that fits inside the bar, the menus wrap onto
           as many rows as they need, and the bar grows to hold them instead of
           spilling its second row over the page. */
        /* A phone keeps the small bar, so the variable must say so too -- otherwise every page
           that sizes itself as "the screen minus the header" reserves 160px on a device whose
           header is 48px, and loses a third of the screen to nothing. */
        :root {
          --tk-header-height: 48px;
        }

        .site-nav,
        .nav-inner {
          height: auto;
          min-height: 48px;
          /* The bar sets width:100% and its own padding, so it needs border-box to stay inside
             the screen. Most pages declare a global reset, but timekeeper_uploader.html and
             demo_preparing.html do not, and there the header was 24px wider than the phone --
             the shared chrome should not depend on what each page happens to reset. */
          box-sizing: border-box;
        }

        .medallion-header-page > .site-nav {
          height: auto;
          min-height: 48px;
        }

        /* The bar's backdrop-filter makes it a containing block for position:fixed, which
           trapped the full-screen sheet inside a 48px header. The bar is opaque navy here, so
           the blur was buying nothing on a phone anyway. */
        .site-nav {
          backdrop-filter: none;
        }

        .nav-inner {
          flex-direction: row;
        }

        /* The phone medallion is set through the SAME variable, so the art inside it and the
           popover hung below it both follow without a second set of numbers. */
        .site-nav {
          --tk-medallion-size: 44px;
        }

        .task-node {
          padding: 3px;
        }

        .task-node-art {
          border-width: 1px;
        }

        .task-node-count {
          right: 0;
          top: 0;
          min-width: 16px;
          height: 16px;
          border-width: 1px;
          padding: 0 3px;
          font-size: 0.6rem;
        }

        /* These are tapped, not pointed at, so the targets grow rather than shrink. */
        .nav-menu-trigger {
          min-height: 44px;
          padding: 8px 11px;
          font-size: 0.78rem;
          white-space: nowrap;
        }

        .nav-dropdown-item {
          min-height: 44px;
        }

        /* One button, one sheet. Three groups and roughly forty actions cannot be a row of
           pills on a phone: unwrapped they are wider than the screen, and wrapped they eat
           the header. A closed dropdown is also still laid out, so leaving them as floating
           panels kept widening the document even while invisible. In the sheet nothing
           floats -- each group is a section and the whole thing scrolls. */
        .nav-menu-toggle {
          display: inline-flex;
          align-items: center;
          gap: 9px;
          min-height: 44px;
          padding: 8px 14px;
          border: 1px solid var(--line);
          border-radius: 9px;
          background: var(--tk-button-bg, transparent);
          color: var(--tk-text);
          font: 850 0.82rem/1 "Source Sans Pro", "Segoe UI", sans-serif;
        }

        .nav-menu-toggle-bars,
        .nav-menu-toggle-bars::before,
        .nav-menu-toggle-bars::after {
          display: block;
          width: 17px;
          height: 2px;
          border-radius: 2px;
          background: currentColor;
        }

        .nav-menu-toggle-bars {
          position: relative;
        }

        .nav-menu-toggle-bars::before,
        .nav-menu-toggle-bars::after {
          content: "";
          position: absolute;
          left: 0;
        }

        .nav-menu-toggle-bars::before { top: -5px; }
        .nav-menu-toggle-bars::after { top: 5px; }

        .nav-menu {
          position: fixed;
          /* `inset: 0` pins all four edges, so the sheet was always exactly screen-height even
             with seven collapsed groups in it -- most of a phone screen of blank panel, and the
             page underneath completely hidden. Pin the top and the sides and leave the bottom
             free, and the sheet ends after the last group. The cap keeps an expanded group
             (Archive Tools is seventeen items) scrolling inside the sheet rather than running
             off the bottom of the screen unreachably. */
          top: 0;
          right: 0;
          left: 0;
          bottom: auto;
          max-height: 100dvh;
          z-index: 200;
          display: none;
          flex: none;
          flex-direction: column;
          /* The bar centres its children; a column sheet needs them full width instead. */
          align-items: stretch;
          margin: 0;
          padding: 0 0 env(safe-area-inset-bottom);
          background: var(--tk-bg-panel);
          overflow-y: auto;
          /* No `overscroll-behavior: contain` here. It stops a gesture inside the sheet from
             chaining to the page, which was right when the sheet was `inset: 0` and the page
             behind it was hidden. The sheet ends after its last group now and its content
             usually fits, so it has nothing to scroll itself -- and `contain` meant a swipe
             anywhere in the top half of the screen did nothing at all: the sheet could not
             move and the page was not allowed to. The page behind is visible and meant to be
             reachable, so a gesture the sheet cannot use belongs to it. */
        }

        .nav-menu.sheet-open {
          display: flex;
        }

        .nav-sheet-head {
          position: sticky;
          top: 0;
          z-index: 1;
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 12px;
          padding: 12px 16px;
          border-bottom: 1px solid var(--line);
          background: var(--tk-bg-panel);
          color: var(--tk-text);
          font-size: 1.05rem;
        }

        .nav-sheet-close {
          min-width: 44px;
          min-height: 44px;
          border: 0;
          background: transparent;
          color: var(--tk-text);
          font-size: 1.7rem;
          line-height: 1;
          cursor: pointer;
        }

        /* Inside the sheet a group is a heading with its items beneath it, so nothing is
           positioned and nothing is hidden behind a second tap. */
        .nav-menu-group {
          position: static;
          width: 100%;
        }

        /* These are the things you navigate to, so in the sheet they stay full-size rows that
           read as tappable. Styling them as small dim section labels buried them under the
           actions, which is the whole reason the first attempt at this failed. The .active
           variants paint parchment-on-ink for the bar and are unreadable here, so the sheet
           states its own colours rather than inheriting a state meant for another surface. */
        .nav-menu.sheet-open .nav-menu-trigger,
        .nav-menu.sheet-open .nav-menu-trigger.active,
        .nav-menu.sheet-open .nav-menu-group.open > .nav-menu-trigger {
          width: 100%;
          justify-content: space-between;
          min-height: 54px;
          margin: 0;
          padding: 12px 16px;
          border: 0;
          border-bottom: 1px solid var(--line);
          border-radius: 0;
          background: transparent;
          box-shadow: none;
          color: var(--tk-text);
          opacity: 1;
          font-size: 1rem;
          font-weight: 850;
          letter-spacing: 0;
          text-transform: none;
          text-align: left;
        }

        /* The caret is the affordance that says a row opens rather than goes somewhere. */
        .nav-menu.sheet-open .nav-caret {
          display: block;
          transition: transform 120ms ease;
        }

        .nav-menu.sheet-open .nav-menu-group.open > .nav-menu-trigger .nav-caret {
          transform: rotate(180deg);
        }

        /* The open section is tinted through its heading and its items, so it reads as one
           block rather than a heading that happens to sit above some rows. */
        .nav-menu.sheet-open .nav-menu-group.open > .nav-menu-trigger {
          background: var(--tk-selected-bg, var(--tk-hover-fill));
          color: var(--tk-selected-text, var(--tk-text));
        }

        /* A <button> centres its own text and an <a> does not, so the two kinds of item in
           these menus disagreed until told otherwise. */
        .nav-menu.sheet-open .nav-dropdown-item {
          justify-content: flex-start;
          min-height: 46px;
          padding: 10px 16px 10px 28px;
          border-radius: 0;
          text-align: left;
        }

        .nav-menu.sheet-open .nav-dropdown-label {
          padding: 8px 16px;
          text-align: left;
        }

        .nav-menu.sheet-open .nav-dropdown {
          position: static;
          /* Collapsed by default; the open group's rule below turns it back on. Declared here
             rather than in a later block so the two cannot fight over source order. */
          display: none;
          gap: 0;
          opacity: 1;
          pointer-events: auto;
          transform: none;
          width: auto;
          min-width: 0;
          max-height: none;
          padding: 0;
          border: 0;
          border-radius: 0;
          box-shadow: none;
          background: transparent;
        }

        .nav-menu.sheet-open .nav-menu-group.open > .nav-dropdown {
          display: grid;
          padding-bottom: 6px;
          background: var(--tk-hover-fill);
        }


        .nav-menu.sheet-open .nav-dropdown::before {
          content: none;
        }

        .footer-inner {
          display: grid;
          justify-items: start;
        }

        /* Only the Archive page carries the fixed drawer button, and at full scroll it sat on
           top of the footer text. The button is 46px tall and offset 60px, so its top edge is
           106px off the bottom -- the clearance has to exceed that, not merely approach it.
           Scoped with :has() so every other footer stays compact. */
        body:has(#mobile-sidebar-toggle) .footer-inner {
          padding-bottom: 118px;
        }

        .global-import-stat-grid,
        .global-import-detail-list div {
          grid-template-columns: 1fr;
        }

        /* A container that exists to scroll its content sideways must not be widened by that
           content. Several pages give their table a min-width so it stays readable; without
           this the container inherits that width and the page carries it. */
        .table-wrap {
          max-width: 100%;
          min-width: 0;
        }

        /* Anything under 16px makes iOS zoom in on focus and leave the page zoomed. */
        input,
        select,
        textarea {
          font-size: 16px;
        }

        /* Keep the press visible, but on-brand instead of the browser's blue box. */
        html {
          -webkit-tap-highlight-color: rgba(185, 130, 94, 0.28);
        }

        :focus-visible {
          outline: 2px solid var(--accent, #B9825E);
          outline-offset: 2px;
        }
      }