/* T4 applet — modern light/dark UI (shared family style) */

:root {
  --accent:        #1565C0;
  --accent-hover:  #1259a8;
  --bg:            #e9eaef;
  --panel-bg:      #f5f5f7;
  --panel-border:  #e0e0e6;
  --card-bg:       #ffffff;
  --text:          #1d1d22;
  --muted:         #6b6b74;
  --faint:         #9a9aa2;
  --tabs-bg:       #e2e2ea;
  --tab-text:      #555;
  --field-bg:      #ffffff;
  --field-border:  #d4d4dc;
  --track:         #d7d7df;
  --sep:           #e2e2e8;
  --shadow:        0 2px 12px rgba(0,0,0,.15);
  --positive:      #21BA45;
}

html.dark {
  --bg:            #17171b;
  --panel-bg:      #26262b;
  --panel-border:  #34343d;
  --card-bg:       #23232a;
  --text:          #e2e2e2;
  --muted:         #a0a0a8;
  --faint:         #77777f;
  --tabs-bg:       #3a3a42;
  --tab-text:      #b9b9c2;
  --field-bg:      #2e2e35;
  --field-border:  #46464f;
  --track:         #47474f;
  --sep:           #3a3a42;
  --shadow:        0 2px 14px rgba(0,0,0,.55);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
               "Helvetica Neue", Arial, sans-serif;
  font-size: 13px;
  color: var(--text);
  background: var(--bg);
  overflow: hidden;
}

#app { display: flex; height: 100vh; }

/* ── Control panel ──────────────────────────────────────────────────── */

#panel {
  width: 340px; min-width: 340px; height: 100vh; height: 100dvh;
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  gap: 6px;
  background: var(--panel-bg);
  border-right: 1px solid var(--panel-border);
  padding: 8px;
  transition: background .25s;
}

#header-row {
  display: flex; justify-content: center; align-items: center;
}
#header-card {
  position: relative;
  /* top padding clears the back link and language switch, which are
     absolutely positioned in the corners */
  width: 100%; border-radius: 10px; padding: 36px 12px 12px;
  text-align: center;
  background: linear-gradient(135deg, #0d3a75 0%, #1565C0 55%, #7E57C2 130%);
  box-shadow: 0 1px 6px rgba(0,0,0,.18);
}

/* back to the hub — the primary way out of an applet */
#hub-back {
  position: absolute; left: 7px; top: 7px;
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px 7px 3px 4px; border-radius: 7px;
  color: rgba(255,255,255,.88);
  background: rgba(0,0,0,.20);
  font-size: 11.5px; line-height: 1; text-decoration: none;
  transition: background .15s, color .15s;
}
#hub-back:hover { background: rgba(0,0,0,.36); color: #fff; }
#hub-back:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* DE / EN switch — same segmented pill as on the hub */
#langswitch {
  position: absolute; right: 7px; top: 7px;
  display: flex; background: rgba(0,0,0,.20);
  border-radius: 7px; padding: 2px; gap: 2px;
}
#langswitch button {
  border: none; border-radius: 5px; min-width: 27px; padding: 2px 5px;
  background: transparent; color: rgba(255,255,255,.75);
  font-family: inherit; font-size: 10.5px; font-weight: 600;
  letter-spacing: .5px; line-height: 1.5; cursor: pointer;
  transition: background .15s, color .15s;
}
#langswitch button:hover { color: #fff; }
#langswitch button.active { background: #fff; color: #0d3a75; }
#langswitch button:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
#header-title {
  /* Normal tracking.  The 3 px the hub uses suits a one-word title; across
     "Physics of the Moka" it reads as stretched. */
  font-size: 25px; font-weight: 800; letter-spacing: normal; color: #fff;
  text-shadow: 0 1px 4px rgba(0,0,0,.35);
}
#header-sub {
  margin-top: 3px; font-size: 11px; letter-spacing: .4px;
  color: rgba(255,255,255,.85);
}

/* ── Tabs (segmented pill) ──────────────────────────────────────────── */

#tabs {
  display: flex; background: var(--tabs-bg); border-radius: 10px;
  padding: 3px; gap: 3px;
}
.tab {
  flex: 1 1 0; display: inline-flex; align-items: center;
  justify-content: center; gap: 6px;
  min-height: 34px; border: none; border-radius: 8px;
  background: transparent; color: var(--tab-text);
  font-size: 12.5px; font-family: inherit; cursor: pointer;
  transition: background .15s, color .15s;
}
.tab:hover { color: var(--text); }
.tab.active {
  background: var(--accent); color: #fff; font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.tab .nabla { font-size: 18px; font-weight: 700; font-style: italic;
              line-height: 1; font-family: Georgia, serif; }

/* ── Scrollable tab content ─────────────────────────────────────────── */

#tab-scroll {
  min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 2px 6px 2px 2px;
  scrollbar-width: thin;
}
.tabpanel { display: flex; flex-direction: column; gap: 6px; }
.tabpanel.hidden { display: none; }

/* The Macro and Micro tabs share one block of controls, mounted through
   wrapper divs. Those wrappers must not generate boxes, or their children
   would fall out of the panel's flex layout and lose the row gap. */
#shared-host-macro,
#shared-host-micro,
#shared-controls { display: contents; }

.sect-title { font-weight: 700; font-size: 13px; margin: 10px 0 0; }
.sect-sub   { font-size: 12.5px; color: var(--muted); font-style: italic;
              margin: 0; line-height: 1.45; }
/* a group label hugs the controls under it and opens a gap above */
.grp-label  { font-size: 12.5px; font-style: italic; color: var(--muted);
              margin: 12px 0 0; }
.info-p     { font-size: 12.5px; line-height: 1.55; margin: 0 0 2px; }

hr.sep { border: none; border-top: 1px solid var(--sep); margin: 4px 0;
         width: 100%; }
/* the rule already marks the break — don't add the group margin on top */
hr.sep + .grp-label,
hr.sep + .sect-title { margin-top: 0; }

/* ── Rows / layout helpers ──────────────────────────────────────────── */

.row { display: flex; align-items: center; gap: 8px; }
.row > span { white-space: nowrap; }
.row.gap { gap: 8px; }
.row.spread { justify-content: space-between; }
.grow { flex: 1; }
.spacer { flex: 1; }
.hidden { display: none !important; }

/* ── Sliders ────────────────────────────────────────────────────────── */

.sldrow { display: flex; align-items: center; gap: 8px; min-height: 26px; }
.sldrow .lbl { min-width: 38px; font-size: 13px; font-style: italic;
               flex: 0 0 auto; }
.sldrow .val {
  min-width: 46px; text-align: right; font-weight: 600; font-size: 12.5px;
  color: var(--text); font-variant-numeric: tabular-nums; flex: 0 0 auto;
}
input[type="range"] {
  -webkit-appearance: none; appearance: none;
  flex: 1; height: 18px; background: transparent; margin: 0; min-width: 0;
  --p: 50%;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 2px;
  background: linear-gradient(to right,
      var(--accent) 0%, var(--accent) var(--p),
      var(--track) var(--p), var(--track) 100%);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--card-bg);
  box-shadow: 0 1px 3px rgba(0,0,0,.3);
  margin-top: -5px; cursor: pointer;
  transition: transform .1s;
}
input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.25); }
input[type="range"]::-moz-range-track {
  height: 4px; border-radius: 2px; background: var(--track);
}
input[type="range"]::-moz-range-progress {
  height: 4px; border-radius: 2px; background: var(--accent);
}
input[type="range"]::-moz-range-thumb {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--card-bg);
  cursor: pointer;
}

/* ── Selects / inputs ───────────────────────────────────────────────── */

select, input[type="text"] {
  font-family: inherit; font-size: 13px; color: var(--text);
  background: var(--field-bg);
  border: 1px solid var(--field-border); border-radius: 7px;
  padding: 5px 8px; outline: none;
  transition: border-color .15s, box-shadow .15s;
}
select { width: 100%; cursor: pointer; }
select:focus, input[type="text"]:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(21,101,192,.18);
}
.row > select { width: auto; flex: 1; }

/* ── Checkboxes ─────────────────────────────────────────────────────── */

label.check {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; cursor: pointer; user-select: none;
  min-height: 22px;            /* the panel's row gap does the spacing */
}
input[type="checkbox"] {
  accent-color: var(--accent);
  width: 15px; height: 15px; margin: 0; cursor: pointer;
}

/* ── Dark-mode switch ───────────────────────────────────────────────── */

label.switch {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  user-select: none;
}
label.switch input { display: none; }
label.switch .track {
  width: 34px; height: 19px; border-radius: 10px; background: var(--track);
  position: relative; transition: background .2s;
}
label.switch .track::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 15px; height: 15px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,.35);
  transition: left .2s;
}
label.switch input:checked + .track { background: var(--accent); }
label.switch input:checked + .track::after { left: 17px; }
.switch-label { font-size: 13px; }

/* ── Buttons ────────────────────────────────────────────────────────── */

.btn {
  border: none; border-radius: 8px; color: #fff;
  font-family: inherit; font-size: 13px; font-weight: 500;
  letter-spacing: .2px; padding: 7px 10px; cursor: pointer;
  transition: filter .12s, transform .05s, box-shadow .12s;
  box-shadow: 0 1px 2px rgba(0,0,0,.18);
}
.btn:hover  { filter: brightness(1.12); box-shadow: 0 2px 5px rgba(0,0,0,.22); }
.btn:active { transform: translateY(1px); filter: brightness(.95); }
/* a button that cannot be pressed has to look it, or the click that does
   nothing reads as the applet being broken */
.btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }
.btn:disabled:hover  { filter: none; box-shadow: none; }
.btn:disabled:active { transform: none; filter: none; }
.btn.full { width: 100%; }

.btn-primary  { background: #1565C0; }
.btn-teal     { background: #00796B; }
.btn-positive { background: #21BA45; }
.btn-negative { background: #C10015; }
.btn-orange   { background: #EF6C00; }
.btn-bluegrey { background: #546E7A; }
.btn-grey     { background: #424248; }
.btn-purple   { background: #7E57C2; }

/* ── Bottom controls / footer ───────────────────────────────────────── */

/* Forward and back on one row: the arrow takes only the width it needs so
   the step keeps its full label, and undoing a step costs no panel height */
.btn.step-back { flex: 0 0 auto; padding: 7px 12px; font-size: 15px;
                 line-height: 15px; }

#panel-bottom { display: flex; flex-direction: column; gap: 5px; }
#panel-bottom .row .btn { max-width: 150px; }
#footer {
  width: 100%; text-align: center; font-size: 10px; color: var(--faint);
  margin-top: 2px;
}
/* fallback route home, always present even when the header bar is slim */
#footer a {
  font-size: 11.5px; font-weight: 500;
  color: var(--accent); text-decoration: none;
}
#footer a:hover { text-decoration: underline; }
#footer a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px;
}

/* ── Responsive: shrink the header on short windows ─────────────────── */

@media (max-height: 780px) {
  #header-title { font-size: 20px; }
  .tab { min-height: 30px; }
}
/* On short windows drop the title but keep a slim bar, so the way back to
   the hub never disappears. */
@media (max-height: 560px) {
  #header-card { padding: 4px 6px; }
  #header-title, #header-sub { display: none; }
  #hub-back { position: static; left: auto; top: auto; }
}

/* ── Plot panel ─────────────────────────────────────────────────────── */

#plotwrap, #graphwrap {
  flex: 1; height: 100vh; height: 100dvh; padding: 14px;
  display: flex; min-width: 0;
}
#plotcard, #plotcard2 {
  flex: 1; min-width: 0; min-height: 0;
  background: var(--card-bg);
  border-radius: 12px;
  border: 1px solid var(--panel-border);
  box-shadow: var(--shadow);
  padding: 6px; overflow: hidden;
  display: flex;
  transition: background .25s;
}
#plot, #plot2 { flex: 1; min-width: 0; min-height: 0;
                width: 100%; height: 100%; }

/* The graphs' own pane, and the dots, exist only in the paged layout. */
#graphwrap { display: none; }
#pager { display: none; }
#floatctl, #floatcut { display: none; }

/* ── Three swipeable panes, on a phone ───────────────────────────────
   The three columns become three screens and the browser does the paging:
   a horizontal snap container needs no gesture code, and gives momentum,
   rubber-banding and keyboard paging for nothing.  The two visual panes are
   separate canvases that map their own sub-rectangle of the same logical
   frame, so no drawing code or constant changes — see app.js REGION_*. */
@media (max-width: 720px) {
  #app {
    overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  #app::-webkit-scrollbar { display: none; }

  #panel, #plotwrap, #graphwrap {
    flex: 0 0 100%; min-width: 100%;
    scroll-snap-align: center; scroll-snap-stop: always;
  }
  #panel { width: auto; }
  #graphwrap { display: flex; }

  /* room under everything for the dots */
  #panel, #plotwrap, #graphwrap { padding-bottom: 22px; }

  /* A horizontal swipe pages; anything else belongs to the canvas, so that
     turning the stove knob does not slide the pane out from under it. */
  #plot, #plot2 { touch-action: pan-x; }

  /* The panel's top control, over the pot and graph panes.  It fades in
     rather than appearing, so that swiping past pane 0 does not flash a
     button at you, and it sits clear of the dots. */
  #floatctl {
    display: flex; gap: 8px;
    position: fixed; left: 14px; right: 14px; bottom: 46px; z-index: 19;
    opacity: 0; pointer-events: none;
    transition: opacity .18s;
  }
  #floatctl.show { opacity: 1; pointer-events: auto; }
  /* It is a control floating over a picture, not a banner across it: the
     buttons size to their own labels and the strip is centred, so the pot
     stays visible on either side of it.  The Start button gets a floor,
     since on its own its label is four letters wide. */
  #floatctl { justify-content: center; }
  #floatctl .row { flex: 0 1 auto; max-width: 100%; }
  #floatctl .btn { box-shadow: 0 3px 10px rgba(0,0,0,.28);
                   flex: 0 1 auto; white-space: nowrap; }
  #floatctl .btn.full { width: auto; min-width: 130px; }
  /* Take apart belongs to the pot, not to its graphs. */
  #floatctl.on-graphs .pot-only { display: none; }
  /* "Fully assembled" is a caption, not a control: it has nothing to say
     out here, where there is no panel around it. */
  #floatctl .sect-title { display: none; }

  /* Cut open, over the pot pane's top right: the caption and the card have
     the top left, and the apparatus itself never reaches that corner in any
     assembly stage.  It fades with the pane like the control strip, and is
     a card rather than bare text so the label stays readable over whatever
     the drawing puts behind it. */
  #floatcut {
    display: block;
    position: fixed; top: 26px; right: 24px; z-index: 19;
    opacity: 0; pointer-events: none;
    transition: opacity .18s;
    background: var(--card-bg); border: 1px solid var(--panel-border);
    border-radius: 8px; padding: 3px 9px;
    box-shadow: 0 3px 10px rgba(0,0,0,.18);
  }
  #floatcut.show { opacity: 1; pointer-events: auto; }
  #floatcut label.check { min-height: 20px; }

  #pager {
    display: flex; justify-content: center; gap: 9px;
    position: fixed; left: 0; right: 0; bottom: 7px; z-index: 20;
    pointer-events: none;
  }
  #pager button {
    pointer-events: auto;
    width: 9px; height: 9px; padding: 0; border: none; border-radius: 50%;
    background: var(--text); opacity: .3; cursor: pointer;
    transition: opacity .15s, transform .15s;
  }
  #pager button.active { opacity: .85; transform: scale(1.35); }
}

/* ── Moka-specific: assembly readout, warnings, equations, references ──── */

/* A derived-quantity table: what the assembly settings imply.  Six rows of
   it, so it is the tallest single block in the panel; it sits a little
   tighter than the control rows above, which are touch targets and cannot. */
.ro { display: flex; flex-direction: column; gap: 1px; }
.ro-row {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; font-size: 12.5px; min-height: 16px;
}
.ro-k { color: var(--muted); }
.ro-v { font-weight: 600; font-variant-numeric: tabular-nums;
        white-space: nowrap; }

/* The symbol list in Theory: a fixed-width symbol column so the letters
   line up and can be scanned, and the meaning wrapping beside it. */
.syms { display: flex; flex-direction: column; gap: 2px; }
.sym-row { display: flex; gap: 9px; font-size: 12.5px; line-height: 1.4; }
.sym-k { flex: 0 0 62px; text-align: right; font-weight: 600;
         font-variant-numeric: tabular-nums; }
.sym-v { flex: 1; color: var(--muted); }

/* a setting the pot cannot be built with — stated, not silently clamped */
.warn {
  font-size: 12.5px; line-height: 1.45;
  color: #C10015; background: rgba(193,0,21,.09);
  border-left: 3px solid #C10015; border-radius: 4px;
  padding: 6px 8px;
}
html.dark .warn { color: #FF6E7A; background: rgba(255,110,122,.10);
                  border-left-color: #FF6E7A; }

/* a slider the pot has been closed on: a temporary refusal, so it is shown
   disabled rather than removed */
input[type="range"]:disabled { opacity: .45; cursor: not-allowed; }
.sldrow.locked .lbl, .sldrow.locked .val { opacity: .55; }

/* display equations inside the Theory paragraphs */
.eq {
  display: block; margin: 4px 0 2px; padding-left: 4px;
  font-style: italic; line-height: 1.7; color: var(--text);
}

/* the reference list */
ol.refs { margin: 2px 0 0; padding-left: 20px; }
ol.refs li { font-size: 11.8px; line-height: 1.45; margin-bottom: 5px;
             color: var(--muted); }
ol.refs li b { color: var(--text); font-weight: 600; }

/* the pot column needs a wider figure than the other applets */
#panel { width: 344px; min-width: 344px; }

/* the view checkbox is built once and mounted into whichever control tab is
   showing; a wrapper that generated a box would drop its children out of
   the panel's flex layout and lose every row gap (DESIGN §3) */
#view-host-build, #view-host-run, #shared-view { display: contents; }
