/* CLAUDE 10-09: the editor screen on a phone (the owner, CapCut 9 on an iPhone). Below 768 px, with a project open
   (phonescreen.js sets body.pe-on), the editor is one fixed screen: a top bar, the preview, a row of controls, the
   timeline, and a bottom toolbar. The left tools panel (aside.library) and the right inspector (aside.inspector) are
   the same elements as on the desktop; here they are restyled as two bottom sheets that slide up over the timeline and
   toolbar and leave the preview visible above them. Nothing on a wider screen changes: every rule that moves the
   layout is inside the phone query and starts with body.pe-on, and the new elements are display:none everywhere else. */

/* CLAUDE 10-18 (design polish B3b): the sheet's height is set on the few elements that use it (phonescreen.js sheetVar). Not
   inherited: a custom property changed on <body> re-styled all 6,400 elements of the editor on every sheet open. */
@property --pe-sheet-h {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}
@property --pe-fl {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

.pe-bar,
.pe-tools,
.pe-rec,
.pe-fullx,
.pe-spacer,
.pe-playhead,
.pe-head,
.pe-key,
.pe-magnet,
.pe-timehead,
.pe-qpop {
  display: none;
}
/* the two side groups of the preview row: invisible wrappers on a wide screen, so the desktop row is as it was. The keyframe
   and Snapping buttons are .tp-btn too, and editor-chrome.css's `main .transport .tp-btn` would show them: out-ranked here. */
.pe-side {
  display: contents;
}
main .transport .pe-key,
main .transport .pe-magnet {
  display: none;
}

@media (max-width: 767.98px) {
  body.pe-on {
    overflow: hidden;
    overscroll-behavior: none;
    /* CLAUDE 10-12: the Graphite tokens (style.css :root) behind the phone editor's names */
    --pe-line: var(--c-line-strong);
    --pe-ink: var(--c-fg);
    --pe-soft: var(--c-fg-3);
    --pe-raise: var(--c-raised);
    --pe-bg: var(--c-canvas);
    --pe-ease: var(--ease-sheet);
    --pe-sheet: #111114; /* a sheet's own background (below), also behind a setting pinned in it (controls.css .pin-set) */
  }
  body.pe-on > header,
  body.pe-on > .skip-link {
    display: none !important;
  }

  /* ----- the one fixed screen ----- */
  body.pe-on main {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: 0;
    max-width: none;
    margin: 0;
    padding: 0;
    gap: 0;
    overflow: hidden;
    background: var(--pe-bg);
    animation: none;
    z-index: 5;
  }
  body.pe-on .stage {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0 0 var(--pe-sheet-h, 0px);
    grid-area: auto;
    max-height: none;
    position: relative;
    /* CLAUDE 10-11 (phone speed): no transition on padding-bottom (nor on #editTimeline's height below). Animating them
       laid the whole stage out on every frame of a sheet opening and redrew the preview canvas each time; the stage now
       changes once and phonescreen.js glides the picture with a transform (flipPreview). */
  }
  body.pe-on .stage > .stage-heading,
  body.pe-on .stage > .stage-note,
  body.pe-on .stage > .trim-bar,
  body.pe-on .stage > #sequenceStrip,
  body.pe-on .stage > #sourceVideo {
    display: none !important;
  }

  /* ----- top bar: back, search, quality, Export ----- */
  body.pe-on .pe-bar {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: none;
    min-height: calc(56px + env(safe-area-inset-top, 0px));
    padding: env(safe-area-inset-top, 0px) max(6px, env(safe-area-inset-right, 0px)) 0
      max(6px, env(safe-area-inset-left, 0px));
    background: var(--pe-bg);
    position: relative;
    z-index: 70;
  }
  body.pe-on .pe-grow {
    flex: 1;
  }
  body.pe-on .pe-ib {
    display: grid;
    place-items: center;
    flex: none;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: var(--r-md);
    background: transparent;
    color: var(--pe-ink);
  }
  body.pe-on .pe-ib:hover,
  body.pe-on .pe-ib:active {
    background: #1b1c20;
  }
  body.pe-on .pe-i {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  body.pe-on .pe-chip {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    height: 44px;
    min-height: 44px;
    padding: 0 6px 0 12px;
    border: 0;
    border-radius: var(--r-pill);
    background: transparent;
    color: var(--pe-ink);
    font-size: 13px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  body.pe-on .pe-chip .pe-i {
    width: 18px;
    height: 18px;
    opacity: 0.7;
    transition: rotate var(--d-ui) var(--ease-out);
  }
  body.pe-on .pe-chip[aria-expanded='true'] .pe-i {
    rotate: 180deg;
  }
  body.pe-on .pe-export {
    height: 44px;
    min-height: 44px;
    min-width: 44px;
    margin-left: 4px;
    padding: 0 20px;
    border: 0;
    border-radius: var(--r-pill);
    background: var(--c-primary);
    color: var(--c-primary-ink);
    font-size: 15px;
    font-weight: 600;
  }
  body.pe-on .pe-export:hover {
    background: var(--c-primary-hover);
  }
  body.pe-on .pe-export:disabled {
    opacity: 0.45;
  }
  body.pe-on .pe-qpop {
    display: block;
    position: absolute;
    top: calc(100% - 4px);
    right: 8px;
    left: 8px;
    padding: 14px;
    border: 0;
    border-radius: var(--r-lg);
    background: var(--c-overlay);
    box-shadow: var(--e-float);
    z-index: 80;
    animation: pe-pop var(--d-ui) var(--ease-out) both;
  }
  body.pe-on .pe-qpop > b {
    display: block;
    margin: 4px 0 8px;
    color: var(--pe-soft);
    font-size: var(--t-label);
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
  }
  body.pe-on .pe-qpop > small {
    display: block;
    margin-top: 12px;
    color: var(--pe-soft);
    font-size: 12px;
    line-height: 1.4;
  }
  body.pe-on .pe-seg {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin-bottom: 12px;
  }
  body.pe-on .pe-seg.pe-fps {
    grid-template-columns: repeat(5, 1fr);
  }
  body.pe-on .pe-seg button {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 56px;
    padding: 6px 4px;
    border: 0;
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.04);
    color: var(--pe-ink);
  }
  body.pe-on .pe-seg.pe-fps button {
    min-height: 48px;
  }
  body.pe-on .pe-seg button b {
    font-size: 15px;
  }
  body.pe-on .pe-seg button small {
    color: var(--pe-soft);
    font-size: var(--t-meta);
  }
  body.pe-on .pe-seg button[aria-checked='true'] {
    border-color: transparent;
    background: rgba(255, 255, 255, 0.1);
    box-shadow: inset 0 0 0 1.5px var(--c-fg);
    color: var(--c-fg);
  }

  /* ----- the preview ----- */
  body.pe-on .stage > .preview-wrap {
    order: 1;
    flex: 1 1 0;
    min-height: 0;
    width: 100%;
    max-width: none;
    height: auto;
    max-height: none;
    margin: 0;
    aspect-ratio: auto;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: #050506;
    transition: none;
  }
  body.pe-on .preview-wrap canvas {
    touch-action: manipulation;
  }
  body.pe-on.pe-noproj .preview-wrap {
    min-height: 40vh;
  }
  body.pe-on.pe-noproj #previewEmpty {
    padding: 24px;
  }

  /* the one-line caption editor a tap on a caption opens (app-captions.js capEditText): full width under the top bar, where
     the keyboard does not cover it, 16 px so iOS does not zoom in */
  /* (the :not()s only raise the specificity above style.css's rule for every plain input) */
  body.pe-on input.cap-edit:not([type='checkbox']):not([type='range']):not([type='color']) {
    left: 12px !important;
    top: calc(64px + env(safe-area-inset-top, 0px)) !important;
    box-sizing: border-box;
    width: calc(100vw - 24px);
    min-height: 48px;
    padding: 0 14px;
    border-radius: var(--r-lg);
    font-size: 16px;
    z-index: 120;
  }

  /* ----- the row, CapCut's (owner 10-12: "play button in weird spot"): full screen and the keyframe on the left, Play
     exactly in the middle, Snapping, undo and redo on the right. Three columns, 1fr 44px 1fr, so Play stays centred
     whatever each side holds; the time is in the timeline's header. ----- */
  body.pe-on .stage > .transport {
    order: 2;
    display: grid;
    grid-template-columns: 1fr 44px 1fr;
    align-items: center;
    flex: none;
    height: 52px;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0 max(8px, env(safe-area-inset-right, 0px)) 0 max(8px, env(safe-area-inset-left, 0px));
    background: var(--pe-bg);
  }
  body.pe-on .transport > #seek,
  body.pe-on .transport > .ratio-pick,
  body.pe-on .transport > #snapBtn,
  body.pe-on .transport > #muteBtn,
  body.pe-on .transport #clock,
  body.pe-on .transport #duration {
    display: none;
  }
  body.pe-on .transport .pe-side {
    display: flex;
    align-items: center;
    min-width: 0;
    grid-row: 1;
  }
  body.pe-on .transport .pe-side-l {
    grid-column: 1;
    justify-self: start;
  }
  body.pe-on .transport .pe-side-r {
    grid-column: 3;
    justify-self: end;
  }
  body.pe-on .transport .tp-btn {
    display: grid;
    place-items: center;
    flex: none;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--pe-ink);
  }
  /* the desktop's #fullBtn is hidden by a container query at this width (editor-chrome.css): shown again here */
  body.pe-on .transport #fullBtn {
    display: grid;
  }
  /* Play: a plain glyph, no disc. 30 px of triangle (or two bars), a 44 px hit area, in the middle column */
  body.pe-on .transport #playBtn.tp-play,
  body.pe-on .transport #playBtn.tp-play:hover {
    grid-column: 2;
    grid-row: 1;
    width: 44px;
    min-width: 44px;
    height: 44px;
    margin: 0;
    background: transparent;
    color: var(--pe-ink);
  }
  body.pe-on .transport #playBtn .ic {
    width: 30px;
    height: 30px;
    fill: currentColor;
    stroke-width: 2.2;
  }
  body.pe-on .transport .tp-btn:not(#playBtn) .ic,
  body.pe-on .transport .tp-btn .pe-i {
    width: 22px;
    height: 22px;
  }
  body.pe-on .transport .pe-key.on {
    color: #ffd54a;
  }
  body.pe-on .transport .pe-key.on .pe-i {
    fill: currentColor;
  }
  /* Snapping on is the icon at full strength; off is dimmed (the toast says which, too) */
  body.pe-on .transport .pe-magnet[aria-pressed='false'] {
    color: var(--c-fg-3);
  }
  body.pe-on .transport .tp-btn:active:not(:disabled) {
    background: rgba(255, 255, 255, 0.07);
  }
  body.pe-on .transport .tp-btn:disabled {
    opacity: 0.32;
  }

  /* the time at the left of the ruler, "00:14 / 00:35": over the ruler's first 28 px, which fades behind it as the tracks
     scroll; taps pass through */
  body.pe-on .pe-timehead {
    display: flex;
    align-items: center;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 7;
    height: 28px;
    padding: 0 22px 0 max(14px, env(safe-area-inset-left, 0px));
    background: linear-gradient(90deg, #0d0d0f calc(100% - 22px), rgba(13, 13, 15, 0));
    color: var(--pe-soft);
    font:
      500 11px/1 'RipClip Mono',
      ui-monospace,
      Consolas,
      monospace;
    font-variant-numeric: tabular-nums;
    white-space: pre;
    pointer-events: none;
  }
  body.pe-on .pe-timehead b {
    color: var(--pe-ink);
    font-weight: 600;
  }

  /* ----- the timeline: the playhead in the middle, the tracks scroll under it ----- */
  body.pe-on #editTimeline {
    order: 3;
    display: flex;
    flex-direction: column;
    flex: none;
    height: min(34dvh, 262px);
    min-height: 168px;
    margin: 0;
    padding: 0;
    border: 0;
    border-top: 1px solid var(--pe-line);
    border-radius: 0;
    background: #0d0d0f;
    overflow: hidden;
    position: relative;
    transition: opacity var(--d-ui) ease;
  }
  body.pe-on.pe-noproj #editTimeline,
  body.pe-on.pe-noproj .transport,
  body.pe-on.pe-noproj .pe-tools {
    display: none;
  }
  body.pe-on #editTimeline .tl-tools,
  body.pe-on #editTimeline .tl-labels {
    display: none;
  }
  body.pe-on .tl-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 0;
    padding: 0;
    overflow-x: auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-x pan-y;
    scrollbar-width: none;
    scroll-behavior: auto;
    -webkit-overflow-scrolling: touch;
  }
  body.pe-on .tl-body::-webkit-scrollbar {
    display: none;
  }
  body.pe-on .pe-spacer {
    display: block;
    flex: none;
    width: 50%;
    height: 1px;
  }
  body.pe-on .tl-body > .tl-tracks {
    flex: none;
    width: calc(100% * var(--tlz, 1));
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 0 0 10px;
    position: relative;
  }
  body.pe-on .tl-ruler {
    display: block !important;
    position: sticky;
    top: 0;
    z-index: 4;
    flex: none;
    height: 28px;
    margin: 0;
    background:
      repeating-linear-gradient(90deg, #34343a 0 1px, transparent 1px 10%) bottom/100% 5px no-repeat,
      #0d0d0f;
    border-bottom: 1px solid var(--pe-line);
    color: #7f838c;
    font-size: 11px;
    cursor: default;
  }
  body.pe-on .tl-ruler span {
    position: absolute;
    top: 5px;
    transform: translateX(-50%);
    white-space: nowrap;
    pointer-events: none;
  }
  body.pe-on .tl-ruler span:first-child {
    transform: none;
  }
  body.pe-on .tl-track {
    flex: none;
    height: 44px;
    line-height: 44px;
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, 0.04);
    overflow: visible;
    position: relative;
  }
  body.pe-on .tl-track[data-track='video'] {
    height: 68px; /* CLAUDE 10-12: frames at the lane's full height, readable (app-timeline.js tlDrawClip draws no wave here) */
    line-height: 68px;
    background: rgba(255, 255, 255, 0.02);
  }
  body.pe-on .tl-track[data-track='background'] {
    height: 30px; /* CLAUDE 10-23 (B4): the Background row, only while the background shows (app-timeline.js) */
    line-height: 30px;
  }
  body.pe-on .tl-track.pe-off {
    display: none;
  }
  body.pe-on .tl-track:empty::after {
    display: none;
  }
  body.pe-on .tl-block {
    top: 3px;
    bottom: 3px;
    font-size: 11px;
    border-radius: var(--r-sm);
  }
  /* CLAUDE 10-18 (owner, iPhone: "you can't drag the boxes after selecting them"): a finger on an UNselected block scrolls
     the tracks (the playhead stays in the middle), a tap selects it and a long press lifts it (phonescreen.js). A SELECTED
     block is the finger's: touch-action none, so a drag moves it in time and its handles trim it, as in CapCut. Moving
     it by its numbers in the editor still works too. No text selection or iOS callout on a block under a long press. */
  body.pe-on .tl-trim {
    touch-action: pan-x pan-y;
  }
  body.pe-on .tl-block {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
  }
  body.pe-on .tl-block.selected,
  body.pe-on .tl-block.tl-lifted {
    touch-action: none;
  }
  /* CLAUDE 10-18 (CapCut): a picture or video layer's block is its own frames with its length in a chip (app-timeline.js tlFilm) */
  body.pe-on .tl-ov.tl-film {
    padding: 0;
    overflow: hidden;
    font-size: 0;
    background-color: #1b1c20;
    background-repeat: repeat-x;
    background-size: auto 100%;
    border-color: transparent;
  }
  body.pe-on .tl-ov.tl-film::after {
    content: attr(data-len);
    position: absolute;
    left: 6px;
    top: 3px;
    padding: 1px 5px;
    border-radius: var(--r-xs);
    background: rgba(0, 0, 0, 0.58);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.3;
    pointer-events: none;
  }
  body.pe-on .tl-block.tl-lifted {
    z-index: 3;
    filter: brightness(1.15);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.55);
    outline: 2px solid var(--c-fg);
    outline-offset: -2px;
  }
  body.pe-on .tl-grip {
    touch-action: none;
    width: 24px;
  }
  body.pe-on .tl-trim:not(.selected) > .tl-grip {
    pointer-events: none;
    opacity: 0;
  }
  body.pe-on .tl-trim.selected > .tl-grip {
    opacity: 1;
  }
  body.pe-on .tl-trim.selected {
    overflow: visible; /* CLAUDE 10-19: its 44 px handles reach past its ends (editor.css), a picture or video layer's too */
  }
  body.pe-on .tl-block b,
  body.pe-on .tl-block > b[title='Remove'] {
    display: none; /* the small × is not a finger target: Delete is in the toolbar */
  }
  body.pe-on .tl-block.selected {
    outline: 2px solid var(--c-fg);
    outline-offset: -2px;
    z-index: 2;
  }
  body.pe-on .tl-playhead {
    visibility: hidden;
  }
  body.pe-on .pe-playhead {
    display: block;
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    margin-left: -1px;
    background: #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55);
    border-radius: 1px;
    pointer-events: none;
    z-index: 8;
  }
  body.pe-on .pe-playhead::before {
    content: '';
    position: absolute;
    top: 0;
    left: -5px;
    width: 12px;
    height: 10px;
    background: #fff;
    clip-path: polygon(0 0, 100% 0, 100% 55%, 50% 100%, 0 55%);
  }
  /* what sits on the main track's two ends */
  body.pe-on .pe-lead-btns {
    position: absolute;
    right: 100%;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 4px;
    padding-right: 8px;
  }
  body.pe-on .pe-lb {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    width: 60px;
    height: 64px;
    min-height: 44px;
    padding: 0 2px;
    border: 0;
    border-radius: var(--r-md);
    background: transparent; /* CLAUDE 10-12 Graphite: an icon and its name, no box */
    color: var(--c-fg-2);
    font-size: var(--t-meta);
    line-height: 1.1;
    text-align: center;
  }
  body.pe-on .pe-lb:active {
    background: rgba(255, 255, 255, 0.06);
  }
  body.pe-on .pe-lb .pe-i {
    width: 20px;
    height: 20px;
    margin: 6px 0; /* the icon sits in a 32 px band, so the two tiles' names line up */
  }
  body.pe-on .pe-lb[aria-pressed='true'] {
    color: var(--c-danger);
  }
  body.pe-on .pe-lb[data-set='1'] {
    color: var(--c-fg);
    box-shadow: none;
  }
  /* Cover: the cover frame (else the first), square, with the pencil that says it can be changed */
  body.pe-on .pe-cov {
    position: relative;
    display: block;
    width: 32px;
    height: 32px;
    margin-bottom: 4px; /* room for the pencil that hangs off the corner */
  }
  body.pe-on .pe-cov canvas {
    display: block;
    width: 32px;
    height: 32px;
    border-radius: var(--r-sm);
    background: var(--c-raised);
  }
  body.pe-on .pe-lb[data-set='1'] .pe-cov canvas {
    box-shadow: 0 0 0 1.5px var(--c-fg);
  }
  body.pe-on .pe-cov .pe-cov-pen {
    position: absolute;
    right: -5px;
    bottom: -5px;
    width: 16px;
    height: 16px;
    margin: 0;
    padding: 3px;
    border-radius: 50%;
    background: var(--c-fg);
    color: #0b0b0d;
    stroke-width: 2.4;
  }
  /* CapCut's small square buttons beside the audio and text lanes: they do what tapping the empty lane does */
  body.pe-on .pe-lane-btn {
    position: absolute;
    right: 100%;
    top: 50%;
    margin-right: 8px;
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.06);
    color: var(--c-fg-2);
    line-height: 1;
  }
  body.pe-on .pe-lane-btn:active {
    background: rgba(255, 255, 255, 0.12);
    color: var(--c-fg);
  }
  body.pe-on .pe-lane-btn .pe-i {
    width: 20px;
    height: 20px;
  }
  body.pe-on .pe-plus {
    position: absolute;
    left: 100%;
    top: 50%;
    margin-left: 10px;
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--pe-ink);
    color: #0b0b0d;
  }
  body.pe-on .pe-plus:active {
    transform: translateY(-50%) scale(0.95);
  }
  body.pe-on .pe-pill {
    position: sticky;
    left: 10px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 100%;
    min-height: 44px;
    padding: 0 14px;
    border: 0; /* CLAUDE 10-12 Graphite: an empty lane's "＋ Add" is quiet text with its icon, not a box */
    border-radius: var(--r-md);
    background: transparent;
    color: var(--c-fg-3);
    font-size: var(--t-body);
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
  }
  body.pe-on .pe-pill .pe-i {
    width: 18px;
    height: 18px;
  }
  body.pe-on .pe-pill:hover,
  body.pe-on .pe-pill:active {
    background: rgba(255, 255, 255, 0.05);
    color: var(--c-fg);
  }

  /* ----- the bottom toolbar ----- */
  body.pe-on .stage > .pe-tools {
    order: 4;
    display: flex;
    align-items: stretch;
    width: 100%;
    flex: none;
    height: calc(68px + env(safe-area-inset-bottom, 0px));
    padding: 0 0 env(safe-area-inset-bottom, 0px);
    border-top: 1px solid var(--pe-line);
    background: var(--pe-bg);
    position: relative;
    z-index: 3;
  }
  body.pe-on .pe-tool-scroll {
    flex: 1;
    min-width: 0;
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0 6px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch; /* momentum */
    touch-action: pan-x;
    overscroll-behavior-x: contain; /* never the page behind */
    scroll-snap-type: x proximity; /* a tile settles at the left edge, a flick still carries on */
    scroll-padding-left: 6px;
    /* CLAUDE 10-18 (design polish B3b): the row fades out at its edges instead of cutting a tile in two. The right edge
       always (more tools are there), the left one only once the row has been scrolled (--pe-fl grows with the scroll,
       below, where scroll-driven animation exists; elsewhere the left edge stays sharp, the right fade still works) */
    -webkit-mask-image: linear-gradient(90deg, transparent, black var(--pe-fl), black calc(100% - 20px), transparent);
    mask-image: linear-gradient(90deg, transparent, black var(--pe-fl), black calc(100% - 20px), transparent);
  }
  @supports (animation-timeline: scroll(x)) {
    body.pe-on .pe-tool-scroll {
      animation: pe-fl linear both;
      animation-timeline: scroll(x self);
      animation-range: 0 24px;
    }
    @keyframes pe-fl {
      from {
        --pe-fl: 0px;
      }
      to {
        --pe-fl: 20px;
      }
    }
  }
  body.pe-on .pe-tool-scroll::-webkit-scrollbar {
    display: none;
  }
  body.pe-on .pe-tools.pe-swap .pe-tool-scroll {
    animation: pe-swap var(--d-ui) var(--ease-out) both;
  }
  body.pe-on .pe-back {
    flex: none;
    display: grid;
    place-items: center;
    width: 48px;
    min-height: 44px;
    padding: 0;
    border: 0;
    border-right: 1px solid var(--pe-line);
    border-radius: 0;
    background: transparent;
    color: var(--pe-ink);
  }
  body.pe-on .pe-back[hidden] {
    display: none;
  }
  /* CLAUDE 10-18: tools pinned at the left of the row (a selected layer's Add overlay): they do not scroll away, a
     divider separates them from the tools that do */
  body.pe-on .pe-tool-pin {
    flex: none;
    display: flex;
    padding: 0 4px 0 6px;
    border-right: 1px solid var(--pe-line);
  }
  body.pe-on .pe-tool-pin[hidden] {
    display: none;
  }
  body.pe-on .pe-tool {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    min-width: 68px; /* 5 and a half tiles at 375 px: the next one peeks, so the row says it scrolls */
    min-height: 56px;
    scroll-snap-align: start;
    padding: 6px 8px 4px;
    border: 0;
    border-radius: var(--r-md);
    background: transparent;
    color: #c9ccd3;
    font-size: 11px;
    font-weight: 500;
    line-height: 1.1;
    white-space: nowrap;
  }
  body.pe-on .pe-tool:active {
    background: #1b1c20;
  }
  body.pe-on .pe-tool:disabled {
    opacity: 0.34;
  }
  body.pe-on .pe-tool .pe-i {
    width: 24px;
    height: 24px;
  }
  body.pe-on .pe-rec {
    display: flex;
    align-items: center;
    gap: 10px;
    position: fixed;
    left: 50%;
    bottom: calc(82px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    min-height: 44px;
    padding: 0 18px 0 14px;
    border: 0;
    border-radius: var(--r-pill);
    background: #d92d3a;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    z-index: 75;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
  }
  body.pe-on .pe-rec[hidden] {
    display: none;
  }
  body.pe-on .pe-rec i {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #fff;
    animation: pe-blink 1.1s ease-in-out infinite;
  }

  /* ----- while a sheet is open the timeline and toolbar give way; the preview and its row stay ----- */
  body.pe-on.pe-sheet #editTimeline {
    height: 0;
    min-height: 0;
    border: 0;
    overflow: hidden;
    visibility: hidden;
  }
  body.pe-on.pe-sheet .stage > .pe-tools {
    visibility: hidden;
    height: 0;
    min-height: 0;
    border: 0;
    padding: 0;
    overflow: hidden;
  }
  body.pe-on.pe-full .stage > .transport {
    display: none;
  }
  body.pe-on.pe-sheet .pe-rec {
    bottom: calc(var(--pe-sheet-h, 0px) + 12px);
  }

  /* ----- the two sheets ----- */
  body.pe-on main > aside.library,
  body.pe-on main > aside.inspector {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    width: auto;
    max-width: none;
    min-height: 0;
    max-height: none;
    height: var(--pe-sheet-h, 46dvh);
    margin: 0;
    padding: 0 0 env(safe-area-inset-bottom, 0px);
    border: 0;
    border-top: 1px solid #2a2b31;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    background: var(--pe-sheet);
    --pin-bg: var(--pe-sheet);
    box-shadow: 0 -18px 52px rgba(0, 0, 0, 0.6);
    z-index: 60;
    transform: translateY(104%);
    visibility: hidden;
    overscroll-behavior: contain;
    /* CLAUDE 10-11: transform only: the sheet's height changes at once (a drag follows the finger with a transform, phonescreen.js
       grabbable); a height transition re-laid out every tile in the grid on each frame.
       CLAUDE 10-18 (design polish P8): out is 260 ms on an ease-out, never ease-in, the way it came; in is below */
    transition:
      transform var(--d-sheet-out) var(--ease-out),
      visibility 0s linear var(--d-sheet-out);
  }
  body.pe-on main > aside.pe-open {
    transform: none;
    visibility: visible;
    transition:
      transform var(--d-sheet) var(--ease-sheet),
      visibility 0s;
  }
  body.pe-on main > aside.inspector {
    overflow-y: auto;
    padding: 0 16px calc(24px + env(safe-area-inset-bottom, 0px));
    display: block;
    --pin-top: 56px; /* CLAUDE 10-20: a pinned setting (controls.css .pin-set) sticks under the sheet's header (.pe-head) */
  }
  body.pe-on aside .pe-head {
    display: flex;
    align-items: center;
    flex: none;
    position: sticky;
    top: 0;
    z-index: 5;
    min-height: 56px;
    margin: 0 -16px;
    padding: 6px 6px 0 16px; /* CLAUDE 10-18: the title sits on the same 16 px gutter as the tabs and rows under it */
    background: #111114;
    touch-action: none;
    cursor: grab;
  }
  body.pe-on main > aside.library .pe-head {
    margin: 0;
  }
  /* CLAUDE 10-20 (owner: "when you add an effect the start seconds thing is weird"): the library's new-effect seconds box
     goes; a tapped effect opens its own sheet with Strength, Start and a Length slider (tiledrop.js effectInspector) */
  body.pe-on .cc-fx-newlen {
    display: none;
  }
  body.pe-on .dnd-where .dnd-at-row button,
  body.pe-on .dnd-where .cc-adjust-value,
  body.pe-on .dnd-where input[type='range'] {
    min-height: var(--h-touch);
  }
  body.pe-on .dnd-where .cc-adjust-value {
    font-size: var(--t-input);
  }
  /* CLAUDE 10-11: an effect's settings (tiledrop.js) fill the sheet; its title and close button are the sheet's own */
  body.pe-on .dnd-inspect .dnd-head {
    display: none;
  }
  /* the text and sound editors hide every other child of the inspector: the sheet's handle stays */
  body.pe-on aside.inspector.layer-open:not(.dnd-on) > .pe-head,
  body.pe-on aside.inspector.audio-open:not(.dnd-on) > .pe-head {
    display: flex !important;
  }
  /* the text editor's own back / duplicate / delete row: the sheet has its close button and the toolbar has Duplicate and
     Delete, so two crosses that mean different things are not shown */
  body.pe-on #layerEd .overlay-head button,
  body.pe-on #audioEd .overlay-head button {
    display: none;
  }
  body.pe-on #layerEd .overlay-card,
  body.pe-on #audioEd .overlay-card {
    border: 0;
    background: transparent;
    box-shadow: none;
    padding: 0;
  }
  body.pe-on .pe-grab {
    position: absolute;
    top: 7px;
    left: 50%;
    width: 38px;
    height: 4px;
    margin-left: -19px;
    border-radius: 2px;
    background: #3b3c43;
  }
  body.pe-on .pe-title {
    margin-top: 6px;
    font-size: 17px;
    font-weight: 650;
    color: var(--pe-ink);
  }
  body.pe-on .pe-head .pe-x {
    margin: 6px 0 0 auto;
  }
  /* the left tools panel: the category row goes (the toolbar picks the category); its sub list is a row of chips */
  body.pe-on main > aside.library.cc-panel {
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }
  body.pe-on aside.library .cc-rail {
    display: none;
  }
  body.pe-on aside.library .cc-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  /* CLAUDE 10-18 (owner: "these are tacky looking menus"; design polish B3b): the sheet's tab rows are the shared .m-tabs
     (controls.css: plain text on one hairline, the open one bright, ONE straight 2 px bar that slides under it, the row
     scrolling sideways and fading at the right edge). phonescreen.js puts the class on them while the phone editor is on.
     What stays here only clears the desktop list's own box (a 112 px column, rows with a vertical bar and a radius). */
  body.pe-on aside.library .cc-subs {
    flex: none;
    width: auto;
    flex-direction: row;
    padding: 0 24px 0 4px; /* the right padding is the fade's width: the last tab clears it at the end of the scroll */
    border-right: 0;
  }
  body.pe-on aside.library .cc-subs:not(:has(> button:nth-child(2))) {
    display: none;
  }
  body.pe-on aside.library .cc-subs button,
  body.pe-on aside.inspector .tabs button {
    justify-content: center;
    min-height: var(--h-touch);
    margin: 0;
    padding: 0 var(--s-3);
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--c-fg-3);
    font-size: 14px;
    font-weight: 550;
  }
  body.pe-on aside.library .cc-subs button::before {
    content: none; /* editor.css's vertical bar at the left of the open row */
  }
  body.pe-on aside.library .cc-subs button.active,
  body.pe-on aside.inspector .tabs button.active {
    border: 0;
    background: transparent;
    color: var(--c-fg);
  }
  /* the second level, a library's own categories (Effects: Trending / Basic / Camera ..., the music and voice libraries,
     Transitions), is the same light chip as the caption template categories (autocaps.css): the open one on a soft
     capsule, never a second underline under the tab row. 30 px to the eye, 44 px to the finger (the ::after). */
  body.pe-on .cc-fx-tabs {
    gap: 2px;
    margin: 0 -4px;
    padding: 7px 24px 7px 4px;
    scroll-padding-inline: 4px; /* the scroll snap would otherwise rest the first chip flush with the edge */
    -webkit-mask-image: linear-gradient(90deg, black calc(100% - 24px), transparent);
    mask-image: linear-gradient(90deg, black calc(100% - 24px), transparent);
  }
  body.pe-on .cc-fx-tabs .cc-fx-tab {
    scroll-margin-inline: 0;
    position: relative;
    min-height: 30px;
    margin: 0;
    padding: 0 12px;
    border-radius: var(--r-lg);
    box-shadow: none;
    color: var(--c-fg-2);
    font-size: 13px;
    transition:
      background-color var(--d-hover) ease,
      color var(--d-hover) ease;
  }
  body.pe-on .cc-fx-tabs .cc-fx-tab::after {
    content: '';
    position: absolute;
    inset: -7px -1px;
  }
  body.pe-on .cc-fx-tabs .cc-fx-tab[aria-selected='true'] {
    background: rgba(242, 240, 235, 0.1);
    box-shadow: none;
    color: var(--c-fg);
  }
  body.pe-on .cc-fx-tabs .cc-fx-tab:focus-visible {
    outline-offset: 0;
  }
  body.pe-on aside.library .cc-content {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 16px calc(32px + env(safe-area-inset-bottom, 0px));
    -webkit-overflow-scrolling: touch;
    --pin-top: -12px; /* CLAUDE 10-20: a pinned setting (controls.css .pin-set) covers the padding, no tile peeks above it */
  }
  /* CLAUDE 10-18: where the sheet cuts the list off (the half-height sheet always does) it fades into the sheet instead of
     slicing a preview in two. An overlay on the scroller's own bottom edge, not a mask on the scroller: a mask on a big
     scrolling list makes iOS Safari composite the whole list off-screen on every scroll frame. The bottom padding above is
     deeper than the fade, so the last row is whole at the end of the scroll. #111114 is the sheet's own colour. */
  body.pe-on aside.library .cc-body {
    position: relative;
  }
  body.pe-on aside.library .cc-body::after {
    content: '';
    position: absolute;
    inset: auto 0 0;
    height: 24px;
    background: linear-gradient(180deg, rgba(17, 17, 20, 0), #111114);
    pointer-events: none;
  }
  /* CLAUDE 10-18 (design polish B3b, P8): the shell first. While a tool's panel waits for the slide to end (phonescreen.js
     panels.open) the sheet shows the shape of what is coming, and the real content then fades in (opacity only). The
     skeleton is a plain block under the title, one shimmer over all of it (the shared m-skel keyframes), nothing that runs
     off screen: it exists only while pe-fill is set. */
  body.pe-on aside.library > .pe-skel {
    display: none;
  }
  body.pe-on aside.library.pe-fill > .pe-skel {
    display: block;
    position: absolute;
    inset: 56px 0 0;
    padding: 0 16px;
    overflow: hidden;
    contain: paint;
    pointer-events: none;
  }
  body.pe-on aside.library.pe-fill > .pe-skel::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.05), transparent);
    transform: translateX(-100%);
    animation: m-skel var(--d-skel) linear infinite;
  }
  body.pe-on aside.library.pe-fill > .cc-body {
    display: none; /* not just hidden: a hidden subtree is still restyled (1,465 nodes) in the sheet's first frame */
  }
  body.pe-on aside.library.pe-filled > .cc-body {
    animation: m-fade var(--d-enter) var(--ease-out) backwards;
  }
  .pe-skel .sk-tabs,
  .pe-skel .sk-chips {
    display: flex;
    align-items: center;
    gap: var(--s-4);
    height: var(--h-touch);
    border-bottom: 1px solid var(--c-line);
  }
  .pe-skel .sk-chips {
    gap: var(--s-2);
    height: 44px;
    border: 0;
  }
  .pe-skel b {
    display: block;
    width: 72px;
    height: 12px;
    border-radius: var(--r-xs);
    background: var(--c-raised);
  }
  .pe-skel .sk-chips b {
    width: 64px;
    height: 30px;
    border-radius: var(--r-pill);
  }
  .pe-skel .sk-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-2);
  }
  .pe-skel .sk-grid i {
    aspect-ratio: 1 / 1.1;
    border-radius: var(--r-md);
    background: var(--c-raised);
  }

  /* a finger and a phone keyboard: fields and buttons in the sheets are 44 px tall, fields 16 px so iOS does not zoom */
  body.pe-on
    aside.pe-open
    :is(
      select,
      textarea,
      input:not([type]),
      input[type='text'],
      input[type='search'],
      input[type='number'],
      input[type='email'],
      input[type='url']
    ) {
    min-height: 44px;
    font-size: 16px;
  }
  body.pe-on
    aside.pe-open
    :is(button, summary):not(.kf-dia):not(.cc-fx *):not(.cc-filter):not(.cc-texttpl *):not(.capfx-cats *):not(
      .cc-fx-tabs *
    ) {
    min-height: 44px;
  }
  /* CLAUDE 10-18: a setting row's name is the same 16 px as its value (the select must be 16 px so iOS does not zoom) */
  body.pe-on aside.pe-open .ac .ac-row,
  body.pe-on aside.pe-open .ac-adv > summary {
    font-size: 16px;
  }
  /* the Style studio's own tab row */
  body.pe-on aside.inspector .tabs {
    display: flex;
    gap: 0;
    margin: 0 -16px 12px;
    padding: 0 24px 0 4px; /* (the scroll, the hairline and the edge fade are .m-tabs / .m-fade-x) */
    border-bottom-color: var(--c-line);
  }
  /* (the tab buttons themselves: the shared quiet tab style with the library's sub list, above) */

  /* ----- the quick sheets (Beats, Cover), search, and the page's own full screen ----- */
  dialog.pe-quick {
    width: 100%;
    max-width: none;
    margin: auto 0 0;
    padding: 6px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    border: 0;
    border-top: 1px solid #2a2b31;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    background: var(--c-surface);
    color: var(--pe-ink);
  }
  dialog.pe-quick::backdrop {
    background: rgba(0, 0, 0, 0.5);
  }
  /* CLAUDE 10-18 (design polish B3b, P8): the small sheets (Beats, Cover) slide like the big ones, CSS only: up in 380 ms on
     the sheet curve, out in 260 ms on an ease-out, and the fade of the shared dialog (motion.css) stays under it */
  dialog.pe-quick {
    translate: 0 100%;
    transition:
      translate var(--d-sheet-out) var(--ease-out),
      opacity var(--d-sheet-out) var(--ease-out),
      overlay var(--d-sheet-out) allow-discrete,
      display var(--d-sheet-out) allow-discrete;
  }
  dialog.pe-quick[open] {
    translate: 0 0;
    transition:
      translate var(--d-sheet) var(--ease-sheet),
      opacity var(--d-ui) ease,
      overlay var(--d-sheet) allow-discrete,
      display var(--d-sheet) allow-discrete;
  }
  @starting-style {
    dialog.pe-quick[open] {
      translate: 0 100%;
    }
  }
  dialog.pe-quick .pe-qhead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 52px;
  }
  dialog.pe-quick .pe-qhead b {
    font-size: 17px;
    font-weight: 650;
  }
  dialog.pe-quick .pe-ib {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--pe-ink);
  }
  dialog.pe-quick .pe-i {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  dialog.pe-quick .pe-qrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    width: 100%;
    min-height: 64px;
    margin-bottom: 8px;
    padding: 10px 16px;
    border: 1px solid var(--c-line-strong);
    border-radius: var(--r-lg);
    background: var(--c-raised);
    color: var(--pe-ink);
    text-align: left;
  }
  dialog.pe-quick .pe-qrow span {
    display: grid;
    gap: 3px;
  }
  dialog.pe-quick .pe-qrow b {
    font-size: 15px;
    font-weight: 600;
  }
  dialog.pe-quick .pe-qrow small {
    color: var(--pe-soft);
    font-size: var(--t-label);
    line-height: 1.35;
  }
  /* CLAUDE 10-18: a row that cannot be used right now (Overlay: Move this clip to a layer with one clip): the title dims, the
     reason stays at full strength */
  dialog.pe-quick .pe-qrow[aria-disabled='true'] {
    cursor: default;
  }
  dialog.pe-quick .pe-qrow[aria-disabled='true'] b {
    opacity: 0.45;
  }
  dialog.pe-quick .pe-sw {
    flex: none;
    position: relative;
    width: 46px;
    height: 28px;
    border-radius: var(--r-lg);
    background: var(--c-overlay);
    transition: background-color var(--d-hover) ease;
  }
  dialog.pe-quick .pe-sw::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #fff;
    transition: transform 220ms var(--ease-spring); /* P15: the knob, springy */
  }
  dialog.pe-quick .pe-qrow[aria-pressed='true'] .pe-sw {
    background: var(--c-signal); /* a switch that is on: the signal green */
  }
  dialog.pe-quick .pe-qrow[aria-pressed='true'] .pe-sw::after {
    transform: translateX(18px);
    background: #061000;
  }
  dialog.pe-quick .pe-qbtn {
    display: block;
    width: 100%;
    min-height: 48px;
    margin-top: 8px;
    border-radius: var(--r-lg);
    font-weight: 600;
  }
  dialog.pe-quick .pe-cover {
    display: flex;
    gap: 14px;
    align-items: center;
    margin: 4px 0 8px;
  }
  dialog.pe-quick .pe-cover p {
    margin: 0;
    color: var(--pe-soft);
    font-size: var(--t-body);
    line-height: 1.45;
  }
  dialog.pe-quick .pe-cover p b {
    display: block;
    color: var(--pe-ink);
    font-size: 20px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }
  dialog.pe-quick .pe-cover p small {
    display: block;
    margin-top: 4px;
    font-size: var(--t-meta);
  }
  dialog.pe-quick .pe-cover-scrub {
    display: block;
    width: 100%;
    height: 44px;
    margin: 0 0 4px;
    accent-color: var(--c-fg);
    touch-action: pan-x;
  }
  dialog.pe-quick .pe-cover-box {
    flex: none;
    border-radius: var(--r-md);
    overflow: hidden;
    border: 1px solid #2a2c33;
    background: #000;
  }
  dialog.pe-quick .pe-cover-pic {
    display: block;
    max-width: 150px;
    height: auto;
  }
  /* CLAUDE 10-19 (owner: "one setting, one home"): on a phone the shape and the background live in the Aspect ratio
     sheet and frame rate / resolution on the quality chip by Export, so the Style tool's Layout tab does not show them a
     second time (the controls stay in the page: the sheet and the chip write through them) */
  body.pe-on #tab-layout label:has(> select[data-key='canvas']),
  body.pe-on #tab-layout #canvasCustom,
  body.pe-on #tab-layout label:has(> select[data-key='layout_mode']),
  body.pe-on #tab-layout #bgOpen,
  /* CLAUDE 10-20: and its zoom, picture crop and playback speed are the selected clip's sheets (Transform, Speed:
     clipinsp.js mirrors), so the Layout tab, reached only from Aspect ratio > Split, is the facecam split alone */
  body.pe-on #tab-layout label:has(> select[data-key='fit_aspect']),
  body.pe-on #tab-layout label:has(> input[data-key='crop_x']),
  body.pe-on #tab-layout label:has(> input[data-key='crop_y']),
  body.pe-on #tab-layout label:has(> select[data-key='speed']),
  body.pe-on #tab-layout label:has(> input[data-key='zoom']),
  body.pe-on #tab-layout > :is(p.hint, .divider),
  body.pe-on #splitControls > p.hint {
    display: none !important;
  }
  /* CLAUDE 10-20 (owner: "one setting, one home"): the Style studio is three sheets here (phonescreen.js openIns sets
     data-pe): Style holds the captions' look only (Presets and the template looks, Font, Caption: the Presets grid is the one way
     to pick a saved preset, so the Saved preset menu above it goes); Overlays and Facecam split are one page each, with
     no tab row. The sheet's own title names it, so the panel's "Style studio" heading goes too. */
  body.pe-on aside.inspector > .section-title,
  body.pe-on aside.inspector > label.field:has(> #presetSelect),
  body.pe-on aside.inspector[data-pe='style'] > .tabs :is([data-tab='layout'], [data-tab='decos']),
  body.pe-on aside.inspector:is([data-pe='layout'], [data-pe='decos']) > :is(.tabs, .preset-actions) {
    display: none;
  }
  /* CLAUDE 10-19: the Aspect ratio sheet (phonescreen.js CMD.ratio): the preview stays clear above it, so each tap shows */
  dialog.pe-quick.pe-ratio::backdrop,
  dialog.pe-quick.pe-live::backdrop {
    background: transparent; /* CLAUDE 10-20: and the Layouts sheet (phonescreen.js CMD.sceneLayouts) */
  }
  dialog.pe-quick .pe-rt-shapes {
    display: flex;
    gap: 8px;
    margin: 0 -16px 14px;
    padding: 0 16px;
    overflow-x: auto;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }
  dialog.pe-quick .pe-rt-shapes::-webkit-scrollbar {
    display: none;
  }
  dialog.pe-quick .pe-rt-shapes button {
    flex: none;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 6px;
    min-width: 60px;
    min-height: 64px;
    padding: 6px 8px;
    border: 0;
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.04);
    color: var(--pe-soft);
  }
  dialog.pe-quick .pe-rt-shapes button i {
    display: block;
    border: 1.5px solid currentColor;
    border-radius: calc(var(--r-xs) / 2);
  }
  dialog.pe-quick .pe-rt-shapes button b {
    font-size: var(--t-label);
    font-weight: 600;
  }
  dialog.pe-quick .pe-rt-shapes button[aria-checked='true'] {
    background: rgba(255, 255, 255, 0.1);
    box-shadow: inset 0 0 0 1.5px var(--c-fg);
    color: var(--c-fg);
  }
  dialog.pe-quick .pe-rt-size {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin: -4px 0 14px;
  }
  dialog.pe-quick .pe-rt-size label {
    display: grid;
    gap: 4px;
    color: var(--pe-soft);
    font-size: var(--t-label);
  }
  dialog.pe-quick .pe-rt-size input {
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--c-line-strong);
    border-radius: 12px;
    background: var(--c-raised);
    color: var(--pe-ink);
    font-size: var(--t-input);
    font-variant-numeric: tabular-nums;
  }
  dialog.pe-quick .pe-rt-h {
    display: block;
    margin-bottom: 8px;
    color: var(--pe-soft);
    font-size: var(--t-label);
    font-weight: 600;
  }
  dialog.pe-quick .pe-rt-more {
    width: 100%;
    min-height: 48px;
    border: 1px solid var(--c-line-strong);
    border-radius: 14px;
    background: var(--c-raised);
    color: var(--pe-ink);
    font-weight: 600;
  }
  dialog.pe-search {
    position: fixed;
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    margin: 0;
    padding: env(safe-area-inset-top, 0px) 0 0;
    border: 0;
    border-radius: 0;
    background: #0d0d0f;
    color: var(--pe-ink);
    overflow-y: auto;
  }
  dialog.pe-search .pe-sbar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 8px 8px 16px;
    border-bottom: 1px solid var(--pe-line);
  }
  dialog.pe-search input {
    flex: 1;
    min-width: 0;
    height: 44px;
    padding: 0 14px;
    border: 1px solid #2a2c33;
    border-radius: var(--r-pill);
    background: #17181c;
    color: var(--pe-ink);
    font-size: 16px; /* iOS zooms into a field under 16 px */
  }
  dialog.pe-search .pe-ib {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--pe-ink);
  }
  dialog.pe-search .pe-i {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  dialog.pe-search .pe-results {
    display: grid;
    padding: 8px 8px calc(24px + env(safe-area-inset-bottom, 0px));
  }
  dialog.pe-search .pe-res {
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 56px;
    padding: 6px 12px;
    border: 0;
    border-radius: var(--r-md);
    background: transparent;
    color: var(--pe-ink);
    text-align: left;
  }
  dialog.pe-search .pe-res:active,
  dialog.pe-search .pe-res:hover {
    background: #17181c;
  }
  dialog.pe-search .pe-res span {
    display: grid;
    gap: 2px;
  }
  dialog.pe-search .pe-res b {
    font-size: 15px;
    font-weight: 600;
  }
  dialog.pe-search .pe-res small {
    color: var(--pe-soft);
    font-size: 12px;
  }
  dialog.pe-search .pe-none {
    margin: 24px 16px;
    color: var(--pe-soft);
    font-size: 14px;
    line-height: 1.5;
  }
  /* the export's progress card sits above the toolbar */
  /* the export's progress and its downloads sit over the top of the preview, so a sheet never hides them */
  body.pe-on .job-card {
    position: fixed;
    left: 12px;
    right: 12px;
    top: calc(64px + env(safe-area-inset-top, 0px));
    bottom: auto;
    width: auto;
    z-index: 65;
    background: rgba(16, 20, 16, 0.96);
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.55);
  }
  body.pe-on .job-card :is(button, a) {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  body.pe-on #toast {
    bottom: calc(84px + env(safe-area-inset-bottom, 0px));
    max-width: calc(100vw - 24px);
    z-index: 95;
  }
  /* full screen where the browser has none (an iPhone): the preview takes the whole screen */
  body.pe-on .preview-wrap.pe-fake {
    position: fixed !important;
    inset: 0 !important;
    z-index: 300;
    background: #000 !important;
    flex: none;
  }
  body.pe-on .pe-fullx {
    display: none;
    position: absolute;
    top: calc(10px + env(safe-area-inset-top, 0px));
    right: 10px;
    z-index: 6;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
  }
  body.pe-on.pe-fakefull .pe-fullx:not([hidden]) {
    display: grid;
  }
  @keyframes pe-pop {
    from {
      opacity: 0;
      transform: translateY(-6px) scale(0.98);
    }
  }
  @keyframes pe-swap {
    from {
      opacity: 0;
      transform: translateX(10px);
    }
  }
  @keyframes pe-blink {
    50% {
      opacity: 0.25;
    }
  }
  /* CLAUDE 10-18 (design polish 3.5, calm not dead): a sheet fades in 180 ms and out in 160 ms, it does not slide; the quick
     popover and the tool row's swap fade; opacity and colour transitions stay; only the recording blink stops */
  @media (prefers-reduced-motion: reduce) {
    body.pe-on main > aside.library,
    body.pe-on main > aside.inspector {
      transform: none;
      opacity: 0;
      transition:
        opacity var(--d-exit) ease,
        visibility 0s linear var(--d-exit);
    }
    body.pe-on main > aside.pe-open {
      opacity: 1;
      transition:
        opacity var(--d-ui) ease,
        visibility 0s;
    }
    body.pe-on .pe-qpop,
    body.pe-on .pe-tools.pe-swap .pe-tool-scroll {
      animation: m-fade var(--d-ui) ease both;
    }
    body.pe-on .pe-rec i,
    body.pe-on aside.library.pe-fill > .pe-skel::after {
      animation: none;
    }
    body.pe-on .pe-chip .pe-i,
    dialog.pe-quick .pe-sw::after {
      transition: none; /* the chevron and the knob jump; the track still fades its colour */
    }
    dialog.pe-quick,
    dialog.pe-quick[open] {
      translate: none;
    }
  }
}

/* CLAUDE 10-12 (phone speed, "editor on mobile feels choppy"): paint costs on a phone.
   1. Loading placeholders stand still. 100+ tiles of a grid (Effects, Filters, Adjust, clip Animations) pulsed or slid a
      gradient at the same time, and the tiles below the fold never finish drawing, so they pulsed for good, even with
      the sheet shut (it waits off screen, not display: none): a style recalculation on every frame of an idle editor,
      1,235 ms in 5 s at 4x CPU (8 ms with the pulse off); opening the Effects sheet cost 476 ms of style work (now 41).
   2. The dimming layer behind a dialog (Quick edit, Add media, a settings sheet) is not blurred: a full-screen
      backdrop-filter re-blurs the live preview canvas behind it on every frame. */
@media (max-width: 767.98px) {
  body.pe-on .cc-fx i.tp-on:not(.tp-ready),
  body.pe-on .cf-sk,
  body.pe-on .cf-skel,
  body.pe-on .at-skeleton span,
  body.pe-on .capfx-skel,
  body.pe-on .dl-skel,
  body.pe-on .ml-skel .ml-cover,
  body.pe-on .ml-skel .ml-text i,
  body.pe-on .mb-skel .mb-thumb,
  body.pe-on .mb-skel i,
  body.pe-on .sl-skel .sl-media,
  body.pe-on .yours-skeleton span {
    animation: none;
  }
  ::backdrop {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}

/* CLAUDE 10-20 (phone QA P1-3): the sheet after an export (app-export.js exportedSheet): the clip, Save to phone, Post
   or schedule, Done. The sheet itself is dialog.pe-quick. */
dialog.exp-done h2 {
  margin: var(--s-3) 0;
  font-size: var(--t-title);
  font-weight: 600;
  text-align: center;
}
dialog.exp-done img {
  display: block;
  height: 180px;
  margin: 0 auto var(--s-4);
  border-radius: var(--r-md);
}
.exp-done-row {
  display: grid;
  gap: var(--s-2);
}
.exp-done-row button {
  min-height: var(--h-touch);
}
