/* CPAL-1.0 License. See chaosaccelerator.com/license.html */

/* Phones, and fingers. Classes layout-mode.js keeps on <html>: layout-mobile(-portrait/
   -landscape) = small window, menus dock bottom or right; input-touch = a touchscreen
   exists; input-coarse = it is the PRIMARY pointer. Loaded last, so it beats every view sheet. */

:root {
  /* Notch, status bar and home indicator (viewport-fit=cover); zero elsewhere. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  /* How much of the bottom/right edge the panel or dock covers; kept by layout-mode.js. */
  --chrome-bottom: 0px;
  --chrome-right: 0px;
  --dock-tab-size: 56px;
}

/* ---- Every layout ---- */

/* 100vh on a phone includes the retracted toolbars; dvh is what shows. vh is the fallback. */
#app {
  height: 100vh;
  height: 100dvh;
}

/* The same correction for the grid's menu height caps (#grid-menu-stack in
   fractal-grid.css); same selectors, so responsive-layout.css's overrides still win. */
@supports (height: 100dvh) {
  #grid-menu-stack {
    max-height: calc(100dvh - var(--panel-inset) * 2);
  }
  .menu-card {
    max-height: calc(100dvh - var(--panel-inset) * 2 - var(--menu-reserved));
  }
  #grid-right-menu-column {
    max-height: calc(100dvh - var(--panel-inset) * 2);
  }
  #grid-right-menu-column .menu-card {
    max-height: calc(100dvh - var(--panel-inset) * 2 - (var(--settings-btn-size) + 8px) * 3);
  }
  .render-progress-card {
    max-height: none;
  }
}

html {
  /* Stops iOS inflating text in landscape. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Double-tap is two taps here, not zoom; pinch-zoom is left alone. */
  touch-action: manipulation;
}
html, body {
  /* No pull-to-refresh or rubber-band from a drag off the map's edge. */
  overscroll-behavior: none;
}
body {
  -webkit-tap-highlight-color: transparent;
}

/* One screen; only panels scroll. Stops a phone dragging the page by a few px. */
html.layout-mobile,
html.layout-mobile body {
  overflow: hidden;
}

#physics-canvas {
  touch-action: none;
}

/* Non-integer scaling of a DPR-capped backing store (gridDpr) turns pixelated rendering into stripes. */
#grid-canvas.is-upscaled {
  image-rendering: auto;
}

.menu-back-chevron {
  display: none;
}

#btn-inspect-point {
  display: none;
  background: transparent;
  border-color: var(--border);
  color: var(--text);
}
#btn-inspect-point.inspect-armed {
  background: var(--accent);
  border-color: var(--accent);
  color: white;
}
html.input-touch #btn-inspect-point,
html.layout-mobile #btn-inspect-point {
  display: inline-block;
}
html.input-touch #inspect-arm-row,
html.layout-mobile #inspect-arm-row {
  gap: 6px;
  align-items: stretch;
}
html.input-touch #inspect-arm-row > button,
html.layout-mobile #inspect-arm-row > button {
  flex: 1 1 0;
  min-width: 0;
  padding-left: 4px;
  padding-right: 4px;
  line-height: 1.2;
}

#grid-dock {
  display: none;
}

/* See "Losing the WebGL context" in fractal-grid.js. */
#grid-context-lost {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  text-align: center;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: rgba(12, 13, 17, 0.9);
}
#grid-context-lost[hidden] {
  display: none;
}
#grid-context-lost p {
  margin: 0;
  max-width: 340px;
}

/* left:50% lays the box out in the right half, so it wrapped at half width. */
.inspect-toast {
  width: max-content;
  max-width: min(320px, calc(100% - 24px));
}

.tip-popover.tip-above::before {
  top: auto;
  bottom: -6px;
  transform: rotate(225deg);
}
.tip-popover.tip-no-arrow::before {
  display: none;
}

/* ---- A finger as the primary pointer ---- */

/* Hover styles stick after a tap on a device that cannot hover; only the misleading ones are put back. */
@media (hover: none) {
  .fractalize-btn:hover {
    transform: none;
    filter: none;
    box-shadow: 0 4px 18px rgba(255, 107, 53, 0.55);
  }
  .inspect-marker:hover {
    background: var(--marker-color);
    border-color: #000;
    display: block;
  }
  .inspect-marker:hover::after {
    content: none;
  }
  #grid-dock-tabs > .menu-toggle:hover {
    background: transparent;
  }
}

html.input-coarse #app {
  /* A long press otherwise starts a text selection (and an iOS callout). */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
html.input-coarse #app textarea,
html.input-coarse #app input,
html.input-coarse #app .inspect-coords-group {
  -webkit-user-select: text;
  user-select: text;
}

/* Fields under 16px make iOS zoom the page on focus, and never back out. */
html.input-coarse select,
html.input-coarse textarea,
html.input-coarse input[type="number"],
html.input-coarse input[type="text"] {
  font-size: 16px;
}
html.input-coarse #grid-view .field select,
html.input-coarse .movie-size input {
  font-size: 16px;
  padding: 8px 8px;
}
html.input-coarse .movie-field input {
  font-size: 16px;
  width: 78px;
  padding: 4px 6px;
}
html.input-coarse .movie-field-arrows button {
  width: 28px;
  height: 18px;
  min-height: 0;
  font-size: 10px;
}

/* Targets: 44px is Apple's minimum, 48dp Android's. */
html.input-coarse button {
  min-height: 40px;
}
html.input-coarse .tool-btn,
html.input-coarse #btn-clear-all {
  min-height: 44px;
}
html.input-coarse .icon-button {
  width: 40px;
  height: 40px;
}
html.input-coarse .speed-btn {
  width: auto;
  min-width: 44px;
}
html.input-coarse .movie-keyframe-actions {
  gap: 6px;
}
html.input-coarse .movie-keyframe-actions .icon-button {
  width: 40px;
  height: 36px;
  min-height: 36px;
  font-size: 15px;
}
html.input-coarse .inspect-row {
  font-size: 13px;
}
html.input-coarse .inspect-row-remove {
  min-width: 40px;
  min-height: 36px;
  font-size: 18px;
}
html.input-coarse .tip-popover-actions button {
  font-size: 13px;
  padding: 6px 12px;
}
html.input-coarse .collapsible > summary {
  font-size: 13px;
  padding: 8px 0;
}
html.input-coarse .collapsible[open] > summary {
  top: -17px;
}
/* Lifted that far, the summary would paint over the readout above it. */
html.input-coarse #separation-details[open] {
  margin-top: 20px;
}
html.input-coarse input[type="range"] {
  min-height: 32px;
}
html.input-coarse .toggle-field {
  min-height: 36px;
}
/* .dual-range draws its own thumbs and only they take pointer events (fractal-grid.css). */
html.input-coarse .dual-range {
  height: 40px;
}
html.input-coarse .dual-range input[type="range"] {
  min-height: 0;
}
html.input-coarse .dual-range input[type="range"]::-webkit-slider-thumb {
  width: 28px;
  height: 28px;
  margin-top: -12px;
}
html.input-coarse .dual-range input[type="range"]::-moz-range-thumb {
  width: 26px;
  height: 26px;
}
html.input-coarse .speed-slider-track {
  width: 44px;
  height: 160px;
}
html.input-coarse .speed-slider-track input[type="range"] {
  width: 160px;
  min-height: 44px;
}

/* ---- The small-window layout: both views ---- */

html.layout-mobile #watermark {
  right: calc(var(--chrome-right) + var(--safe-right) + 10px);
  bottom: calc(max(var(--chrome-bottom), var(--safe-bottom)) + 8px);
  font-size: 11px;
  opacity: 0.85;
}

html.layout-mobile #transition-skip {
  bottom: calc(max(var(--chrome-bottom), var(--safe-bottom)) + 16px);
}

/* ---- The small-window layout: the editor ---- */

#editor-topbar {
  display: none;
}
html.layout-mobile #editor-topbar {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: 8px;
  padding: calc(6px + var(--safe-top)) calc(10px + var(--safe-right)) 6px calc(10px + var(--safe-left));
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
}
#editor-topbar #playback-toolbar {
  position: static;
  transform: none;
  flex: 1 1 auto;
  min-width: 0;
  align-items: stretch;
  gap: 2px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
#editor-topbar #playback-toolbar .playback-controls {
  gap: 6px;
}
#editor-topbar #playback-toolbar .readout {
  text-align: center;
}
#editor-topbar .floating-settings-btn,
#editor-topbar .floating-home-btn {
  position: static;
  flex-shrink: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: transparent;
}
html.layout-mobile .settings-panel {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  max-width: none;
  max-height: none;
  border: 0;
  border-radius: 0;
  z-index: 60;
  background: var(--bg-panel);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transform-origin: top center;
}
html.layout-mobile .settings-panel-header {
  padding: calc(14px + var(--safe-top)) calc(16px + var(--safe-right)) 14px calc(16px + var(--safe-left));
}
html.layout-mobile .settings-panel-body {
  padding: 16px calc(16px + var(--safe-right)) calc(16px + var(--safe-bottom)) calc(16px + var(--safe-left));
}
html.layout-mobile #fractalize-wrap {
  bottom: 16px;
}
html.layout-mobile .fractalize-btn {
  font-size: 16px;
  padding: 12px 28px;
}

html.layout-mobile #step-readout {
  display: none;
}
/* Opening Map Evolution in the phone dock turns Playback on (fractal-grid.js), so no switch. */
html.layout-mobile .toggle-field:has(#evolution-inspect-checkbox) {
  display: none;
}
/* The phone dock has no Movie card, so its settings would do nothing. */
html.layout-mobile :is(#movie-friction-field, #movie-center-lines-field) {
  display: none;
}

/* A fade along the bottom while there is more to scroll (layout-mode.js sets .scroll-more). */
html.layout-mobile :is(#panel, #grid-dock-sheet).scroll-more::after {
  content: "";
  position: sticky;
  bottom: 0;
  display: block;
  flex: none;
  height: 48px;
  margin-top: -48px;
  background: linear-gradient(transparent, var(--bg-panel));
  pointer-events: none;
}
/* The panel's flex gap would add space before the fade; its bottom padding would lift it off the edge. */
html.layout-mobile #panel.scroll-more::after {
  bottom: calc(-1 * var(--panel-pad-bottom));
  margin-top: calc(-48px - var(--panel-gap));
}

/* One height in both modes, so switching mode never reshapes the scene area (and so the frame). */
html.layout-mobile-portrait #panel {
  --panel-gap: 16px;
  --panel-pad-bottom: calc(14px + var(--safe-bottom));
  height: 45dvh;
  padding: 14px 14px var(--panel-pad-bottom) 14px;
  gap: var(--panel-gap);
  overscroll-behavior: contain;
}
/* Simple Mode has less to show: its sections spread out to fill that height. */
html.simple-mode.layout-mobile-portrait #panel > .panel-section {
  margin-block: auto;
}
html.layout-mobile-landscape #panel {
  --panel-gap: 14px;
  --panel-pad-bottom: 12px;
  width: calc(268px + var(--safe-left));
  padding: 12px 12px 12px calc(12px + var(--safe-left));
  gap: var(--panel-gap);
  overscroll-behavior: contain;
}

/* ---- The small-window layout: the grid ---- */

html.layout-mobile #grid-menu-column {
  top: calc(var(--panel-inset) + var(--safe-top));
  left: calc(var(--panel-inset) + var(--safe-left));
  width: auto;
  max-width: calc(100% - var(--panel-inset) * 2 - var(--safe-left) - var(--safe-right));
}
html.layout-mobile .menu-back {
  width: var(--settings-btn-size);
  height: var(--settings-btn-size);
  padding: 0;
  justify-content: center;
}
html.layout-mobile .menu-back-label {
  display: none;
}
html.layout-mobile .menu-back-chevron {
  display: block;
  margin-right: 2px;
}
html.layout-mobile #menu-render-progress {
  left: calc(var(--panel-inset) + var(--safe-left));
  bottom: var(--panel-inset);
}
html.layout-mobile .render-progress-toggle {
  top: calc(2px - max(0px, var(--safe-bottom) - var(--chrome-bottom)));
}
/* Left column keeps only the back link; the right (the Movie menu) is hidden whole.
   .dock-active, not the layout class alone: menus leave only once the dock has them (setDockActive). */
#grid-view.dock-active #grid-right-menu-column {
  display: none;
}

html.layout-mobile #grid-main {
  min-width: 0;
  min-height: 0;
}
html.layout-mobile-landscape #grid-view {
  flex-direction: row;
}

html.layout-mobile #grid-dock {
  display: flex;
  flex-shrink: 0;
  position: relative;
  /* Below the editor #panel's transitional z-index 4 (app-shell.css) so it fades over the grid. */
  z-index: 2;
  min-width: 0;
  min-height: 0;
  background: var(--bg-panel);
}
html.layout-mobile-portrait #grid-dock {
  flex-direction: column;
  width: 100%;
  border-top: 1px solid var(--border);
}
html.layout-mobile-landscape #grid-dock {
  flex-direction: row;
  height: 100%;
  border-left: 1px solid var(--border);
}

/* The sheet: the one open card. Out of the layout while nothing is open (layoutDock in fractal-grid.js). */
#grid-dock-sheet {
  display: none;
  min-width: 0;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
#grid-view.dock-sheet-open #grid-dock-sheet {
  display: block;
}
html.layout-mobile-portrait #grid-dock-sheet {
  width: 100%;
  border-bottom: 1px solid var(--border);
}
html.layout-mobile-landscape #grid-dock-sheet {
  width: min(340px, 46vw);
  height: 100%;
  border-right: 1px solid var(--border);
}

/* A card in the sheet is a section: full width, no chrome, no title line (the lit
   tab beneath names and closes it). The SHEET scrolls, so a card's body must not. */
#grid-dock-sheet > .menu-card {
  width: 100%;
  max-width: none;
  max-height: none;
  overflow: visible;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  animation: none;
}
#grid-dock-sheet > .menu-card > .menu-card-header {
  display: none;
}
#grid-dock-sheet > .menu-card > .menu-card-body {
  overflow: visible;
  padding: 12px 14px 14px 14px;
}
#grid-dock-sheet > #grid-display-panel > .menu-card-body {
  padding: 12px 6px 8px 6px;
}
#grid-dock-sheet .display-mode-row img {
  width: 34%;
  max-width: 150px;
}

/* Inspect, re-ordered: sections dissolved (display: contents) so the arm buttons
   come first, then the preview, then the rest; a finger has no hover. */
#grid-dock-sheet > #grid-inspect-panel > .menu-card-body > .panel-section {
  display: contents;
}
#grid-dock-sheet #inspect-arm-row { order: 1; }
#grid-dock-sheet #hover-preview { order: 2; }
#grid-dock-sheet #hover-playback-controls { order: 3; margin-top: 0; }
#grid-dock-sheet #hover-readout { order: 4; margin: 0; }
#grid-dock-sheet #inspect-progress { order: 4; margin: 0; }
#grid-dock-sheet #grid-inspect-panel .section-label { order: 5; margin: 4px 0 0 0; }
#grid-dock-sheet #grid-inspect-panel .tool-grid { order: 6; }
#grid-dock-sheet #btn-inspect-clear-all { order: 7; margin-top: 0; }
#grid-dock-sheet #inspect-list { order: 8; margin-top: 0; }
#grid-dock-sheet #inspect-list:empty { display: none; }
#grid-dock-sheet #separation-details { order: 4; margin-top: 0; }
#grid-dock-sheet #separation-details[open] { margin-top: 20px; }
#grid-dock-sheet #hover-preview {
  width: min(100%, 230px);
  align-self: center;
}

#grid-dock-tabs {
  display: flex;
  flex-shrink: 0;
  min-width: 0;
  min-height: 0;
}
html.layout-mobile-portrait #grid-dock-tabs {
  flex-direction: row;
  width: 100%;
  padding: 0 var(--safe-right) var(--safe-bottom) var(--safe-left);
}
html.layout-mobile-landscape #grid-dock-tabs {
  flex-direction: column;
  width: calc(var(--dock-tab-size) + 8px + var(--safe-right));
  height: 100%;
  padding: 0 var(--safe-right) var(--safe-bottom) 0;
  overflow-y: auto;
  scrollbar-width: none;
}
#grid-dock-tabs > .menu-toggle {
  flex: 1 1 0;
  min-width: 0;
  width: auto;
  height: var(--dock-tab-size);
  min-height: 44px;
  flex-direction: column;
  gap: 4px;
  padding: 0 2px;
  font-size: 18px;
  color: var(--text-dim);
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  position: relative;
}
html.layout-mobile-landscape #grid-dock-tabs > .menu-toggle {
  width: 100%;
  height: auto;
  flex: 1 1 var(--dock-tab-size);
  max-height: 72px;
}
#grid-dock-tabs > .menu-toggle::after {
  content: attr(data-tab-label);
  font-size: 10px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
#grid-dock-tabs > .menu-toggle > svg {
  flex-shrink: 0;
}
#grid-dock-tabs > .menu-toggle[aria-expanded="true"] {
  color: var(--accent);
}
#grid-dock-tabs > .menu-toggle[aria-expanded="true"]::before {
  content: "";
  position: absolute;
  background: var(--accent);
  border-radius: 2px;
}
html.layout-mobile-portrait #grid-dock-tabs > .menu-toggle[aria-expanded="true"]::before {
  top: -1px;
  left: 18%;
  right: 18%;
  height: 2px;
}
html.layout-mobile-landscape #grid-dock-tabs > .menu-toggle[aria-expanded="true"]::before {
  left: -1px;
  top: 18%;
  bottom: 18%;
  width: 2px;
}

html.layout-mobile #editor-settings-mount > .menu-card-body {
  padding: 16px calc(16px + var(--safe-right)) calc(16px + var(--safe-bottom)) calc(16px + var(--safe-left));
}
