  /* --- Disk Panel --- */
  .disk-panel {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 110px);
  }

  /* --- Disk Header --- */
  .disk-header {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 14px 16px;
    background: var(--selected-bg);
    border: 1px solid var(--accent);
    border-radius: 4px 4px 0 0;
    flex-shrink: 0;
    color: var(--selected-text);
  }

  .disk-header-spacer {
    width: 48px;
    flex-shrink: 0;
    text-align: right;
    color: var(--text-muted);
  }

  .disk-name {
    flex: 1;
    /* Override the default flex `min-width: auto` (which equals the
       child's min-content) so .disk-name can shrink below 18ch on
       narrow screens — otherwise the .disk-id flex-shrink:0 sibling
       gets pushed past the header's right edge. */
    min-width: 0;
    font-size: 16px;
    color: var(--text-muted);
    letter-spacing: 1px;
    white-space: pre;
  }

  .disk-name .editable,
  .disk-id .editable {
    display: inline-block;
    padding: 2px 4px;
    border-radius: 3px;
    cursor: pointer;
    font-family: 'C64 Pro Mono', monospace;
  }

  .disk-name .editable {
    min-width: 18ch;
  }

  /* ── Narrow viewports ────────────────────────────────────────────
     Below ~600px the 16px C64 Pro Mono header line ("0 \"NAME      \" ID 2A")
     no longer fits in one row on a phone. Drop the font size and tighten
     padding first; below ~420px allow the header to wrap so the disk-id
     drops to its own right-aligned row. */
  @media (max-width: 600px) {
    .disk-header { padding: 10px 12px; gap: 6px; }
    .disk-name { font-size: 13px; letter-spacing: 0; }
    .disk-id { font-size: 12px; }
    .disk-header-spacer { width: 24px; }
    .disk-name .editable { min-width: 0; }
  }
  @media (max-width: 420px) {
    .disk-header { flex-wrap: wrap; }
    /* Force disk-id to its own row, right-aligned. spacer + disk-name
       stay together on row 1. */
    .disk-id { flex: 1 1 100%; text-align: right; }
  }

  .disk-id .editable {
    min-width: 6ch;
  }

  .disk-name .editable.empty,
  .disk-id .editable.empty {
    background: var(--placeholder-bg);
    min-height: 1.4em;
  }

  .disk-name .editable:hover,
  .disk-id .editable:hover {
    background: var(--hover-edit);
  }

  .disk-name .editable.editing,
  .disk-id .editable.editing {
    background: none;
    outline: none;
    padding: 0;
    cursor: text;
  }

  .disk-id {
    width: auto;
    min-width: 6ch;
    font-size: 14px;
    color: var(--text-muted);
    text-align: left;
    flex-shrink: 0;
    white-space: pre;
  }

  /* --- Directory Listing --- */
  /* Top/bottom padding doubles as the drop zone for placing files at the
     very start or end of the listing — too thin and the cursor target is
     unhittable. */
  .dir-listing {
    font-size: 14px;
    line-height: 1;
    overflow-y: auto;
    flex: 1;
    min-height: 200px;
    padding: 18px 0;
    border-left: 1px solid var(--accent);
    border-right: 1px solid var(--accent);
  }

  .dir-entry {
    display: flex;
    gap: 8px;
    padding: 0 16px;
    /* Suppress iOS Safari's native long-press callout (copy/select) so
       our 500ms timer can fire showContextMenu instead. */
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }

  .dir-entry {
    cursor: pointer;
  }

  .dir-header-row {
    cursor: default;
    font-size: 11px;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    border-left: 1px solid var(--accent);
    border-right: 1px solid var(--accent);
    padding-bottom: 4px;
  }

  .dir-parent-row {
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    padding-bottom: 4px;
    margin-bottom: 4px;
  }

  .dir-parent-row:hover {
    background: var(--hover);
  }

  .dir-header-row .dir-blocks,
  .dir-header-row .dir-name,
  .dir-header-row .dir-type,
  .dir-header-row .dir-ts,
  .dir-header-row .dir-addr {
    color: var(--text-muted);
    font-size: 11px;
    font-family: inherit;
  }

  .dir-header-row:hover {
    background: none;
  }

  .dir-entry:not(.dir-header-row):not(.selected):hover {
    background: var(--hover);
  }

  .dir-entry.selected {
    background: var(--selected-bg);
    color: var(--selected-text);
  }

  .dir-entry.selected:hover {
    filter: brightness(1.15);
  }

  .dir-entry.selected .dir-blocks,
  .dir-entry.selected .dir-type,
  .dir-entry.selected .dir-addr,
  .dir-entry.selected .dir-ts,
  .dir-entry.selected .dir-icons {
    color: var(--selected-text);
  }

  .dir-icons {
    width: 36px;
    flex-shrink: 0;
    text-align: left;
    font-size: 11px;
    display: flex;
    gap: 6px;
  }

  .dir-icon-info, .dir-icon-geos, .dir-icon-tape {
    cursor: pointer;
    color: var(--text-muted);
    opacity: 0.7;
  }
  .dir-icon-recover { color: var(--color-recover); opacity: 0.8; }
  .dir-icon-recover-partial { color: var(--color-recover-partial); opacity: 0.8; }
  .dir-icon-recover-no { color: var(--color-recover-no); opacity: 0.8; }

  .dir-icon-info:hover, .dir-icon-geos:hover, .dir-icon-tape:hover {
    color: var(--accent);
    opacity: 1;
  }

  .dir-entry.selected .dir-icon-info:hover,
  .dir-entry.selected .dir-icon-geos:hover,
  .dir-entry.selected .dir-icon-tape:hover {
    color: var(--selected-text);
    opacity: 0.8;
  }

  .dir-blocks {
    width: 48px;
    text-align: right;
    color: var(--text-muted);
    flex-shrink: 0;
  }

  .blocks-input {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--accent);
    border-radius: 3px;
    padding: 0 4px;
    color: var(--text);
    font-family: inherit;
    font-size: inherit;
    text-align: right;
    outline: none;
    -moz-appearance: textfield;
  }

  .blocks-input::-webkit-inner-spin-button,
  .blocks-input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }

  .hex-input {
    width: 3ch;
    background: var(--bg);
    border: 1px solid var(--accent);
    border-radius: 3px;
    padding: 0 3px;
    color: var(--text);
    font-family: inherit;
    font-size: inherit;
    text-align: center;
    outline: none;
    text-transform: uppercase;
  }

  .hex-input.invalid {
    border-color: var(--color-error);
    color: var(--color-error);
  }

  .hex-input-group {
    display: inline-flex;
    gap: 3px;
    align-items: center;
  }

  .hex-input-sep {
    color: var(--text-muted);
    font-size: 10px;
  }

  .dir-name {
    flex: 1;
    white-space: pre;
    font-family: 'C64 Pro Mono', monospace;
  }

  .name-input, .header-input {
    width: 100%;
    box-sizing: border-box;
    background: var(--bg);
    border: 1px solid var(--accent);
    border-radius: 3px;
    padding: 0 4px;
    color: var(--text);
    font-family: inherit;
    font-size: inherit;
    letter-spacing: inherit;
    outline: none;
  }

  .dir-type {
    width: 5ch;
    text-align: left;
    color: var(--text-muted);
    flex-shrink: 0;
    white-space: pre;
    position: relative;
  }

  .dir-slot {
    width: 3ch;
    text-align: right;
    color: var(--text-muted);
    flex-shrink: 0;
    white-space: pre;
    margin-right: 8px;
  }

  .dir-addr {
    width: 11ch;
    text-align: left;
    color: var(--text-muted);
    flex-shrink: 0;
    font-size: 12px;
    white-space: pre;
    display: none;
  }

  .show-addresses .dir-addr {
    display: block;
  }

  .dir-ts {
    width: 7ch;
    text-align: left;
    color: var(--text-muted);
    flex-shrink: 0;
    font-size: 12px;
    white-space: pre;
    display: none;
  }

  .show-tracksector .dir-ts {
    display: block;
  }

  .dir-grip {
    width: 16px;
    flex-shrink: 0;
    cursor: grab;
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
    opacity: 0;
    transition: opacity 0.15s;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Without this, a vertical touch on the grip is intercepted by the
       .dir-listing's scrolling (overflow-y: auto) and pointermove never
       fires for our drag handler. */
    touch-action: none;
  }

  .dir-entry:hover .dir-grip {
    opacity: 0.5;
  }

  .dir-entry.selected .dir-grip {
    color: var(--selected-text);
  }

  /* On touch devices there's no hover, so the grip is only visible for
     the currently-selected row — that's the one the user can drag. */
  @media (hover: none) and (pointer: coarse) {
    .dir-entry.selected .dir-grip { opacity: 1; }
  }

  .dir-header-row .dir-grip {
    cursor: default;
    opacity: 0 !important;
  }

  /* Drop indicator: a 5px accent-colored bar sitting in the gap above or
     below the hovered row. Pseudo-element so we don't disturb row layout
     and the bar reads as a clear "between rows" target instead of an
     edge-line stuck to one row. */
  .dir-entry.drag-over-top,
  .dir-entry.drag-over-bottom {
    position: relative;
  }
  .dir-entry.drag-over-top::before,
  .dir-entry.drag-over-bottom::after {
    content: '';
    position: absolute;
    left: 4px;
    right: 4px;
    height: 5px;
    background: var(--accent);
    border-radius: 3px;
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.4);
    z-index: 5;
    pointer-events: none;
  }
  .dir-entry.drag-over-top::before { top: -3px; }
  .dir-entry.drag-over-bottom::after { bottom: -3px; }

  .dir-entry.dragging {
    opacity: 0.4;
  }

  /* Cloned dragstart-time element used as the browser's drag image. Lives
     offscreen just long enough for the browser to snapshot it. Strong
     contrast + shadow makes the resulting ghost much easier to track than
     the default semi-transparent screenshot. */
  .dir-entry.drag-ghost {
    position: absolute;
    top: -2000px;
    left: -2000px;
    background: var(--bg);
    border: 2px solid var(--accent);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
    opacity: 1;
    pointer-events: none;
  }

  .type-dropdown {
    position: fixed;
    background: var(--bg-menu);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 4px 0;
    min-width: 80px;
    z-index: 200;
    box-shadow: 0 4px 16px rgba(0,0,0,.25);
  }

  .type-dropdown .type-option {
    padding: 4px 10px 4px 26px;
    cursor: pointer;
    white-space: nowrap;
    position: relative;
    color: var(--text);
  }

  .type-dropdown .type-option .check {
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 10px;
  }

  .type-dropdown .type-option:hover {
    background: var(--hover);
  }

  .dir-footer {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 16px;
    background: var(--selected-bg);
    border: 1px solid var(--accent);
    border-top: none;
    border-radius: 0 0 4px 4px;
    color: var(--selected-text);
    font-size: 13px;
    flex-shrink: 0;
  }

  .dir-footer-row {
    display: flex;
    gap: 8px;
    align-items: center;
  }

  .dir-footer-blocks {
    width: 48px;
    text-align: right;
    flex-shrink: 0;
  }

  .dir-footer-label {
    flex: 1;
  }

  .dir-footer-tracks {
    font-size: 11px;
    opacity: 0.6;
  }

  .dir-footer-ts {
    flex-shrink: 0;
  }

  .dir-footer-health {
    font-size: 16px;
    flex-shrink: 0;
    margin-left: 4px;
    cursor: pointer;
  }

  .dir-footer-health.health-ok { color: var(--c64-string); }
  .dir-footer-health.health-warn { color: var(--c64-highlight); }
  .dir-footer-health.health-error { color: var(--c64-control); }

  .dir-entry.deleted {
    opacity: 0.5;
  }

  /* Reversed PETSCII chars ($00-$1F, $80-$9F): swap fg/bg with the
     surrounding letters, matching how a C64 draws them. */
  .petscii-rev, .petscii-editor .pe-rev {
    background: var(--text);
    color: var(--bg);
    border-radius: 2px;
  }
  /* On a selected row the surrounding palette changes, so invert against
     the selected colors instead of the default ones. */
  .dir-entry.selected .petscii-rev {
    background: var(--selected-text);
    color: var(--selected-bg);
  }

  /* Contenteditable PETSCII editor (replaces <input> for filename rename
     so reversed bytes $00-$1F / $80-$9F round-trip losslessly). */
  .petscii-editor {
    outline: none;
    white-space: pre;
    min-height: 1em;
    user-select: text;
    -webkit-user-select: text;
  }
  .petscii-editor .pe-char {
    display: inline-block;
  }

