/* ═══════════════════════════════════════════════════════════════════════════
 *  The ELT poster studio's own styles — and ONLY its own.
 *
 *  AI NOTES
 *  ────────
 *  LOADED LAST, after assets/chrome.css and assets/base.css. What is left here
 *  is the studio: the control panel, the 300-DPI canvas stage, the picker and
 *  the modals. No other tool has any of it.
 *
 *  IT USED TO BE A <style> BLOCK INSIDE index.php — a hundred lines of palette,
 *  reset, header and layout inlined in the page, which meant it could not be
 *  cached, could not be edited from /template/ → Styles, and was a fourth
 *  private copy of a design the other three tools also each had a copy of.
 *
 *  THE TOKENS BELOW ARE ALIASES, NOT VALUES. This tool spells almost all of
 *  them differently from the rest of the site — --text, --head, --muted,
 *  --accent, --radius — and its own rules use those names several hundred
 *  times. Pointing them at the central ones is a handful of lines instead of a
 *  rewrite, and it means the palette in /template/ → Styles moves this tool
 *  with everything else.
 * ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* this tool's spelling  →  the site's */
  --bg2:    var(--bg-raise);
  --text:   var(--ink);
  --head:   var(--ink-bright);
  --muted:  var(--ink-dim);
  --accent: var(--go);
  --danger: var(--bad);
  --radius: var(--r-lg);

  /* ITS OWN. A translucent panel over the page rather than a solid raised one:
     the studio stacks panels on panels and a solid fill at every level reads
     as a stack of boxes. */
  --panel: rgba(255, 255, 255, .045);
}

/* THE POSTER TYPEFACE IS THE UI TYPEFACE HERE, on purpose: the controls set
   the text that goes on the poster, so the two should look like the same
   words. Source Sans 3 is the open Myriad Pro equivalent and is self-hosted —
   the CSP on this page blocks CDNs. */
body { font-family: 'Source Sans 3', var(--sans); font-size: 16px; }

/* THE STUDIO IS WIDER THAN A READING COLUMN. base.css gives main.wrap a 62rem
   measure, which is right for a page of prose and far too narrow for a canvas
   beside a control panel; .eltp-wrap below does this tool's width instead. */
body[data-page="studio"] main.wrap { max-width: none; padding: 0; }

/* A LABEL HERE IS A SENTENCE, NOT A CAPTION. base.css styles a bare <label>
   small, letter-spaced and UPPERCASE, which is the field-caption convention
   the other tools grew; this studio writes "Move portrait" and means it.
   BLANKET RATHER THAN PER-RULE, because the labels in this file are variously
   classed, unclassed and inline-styled, and the inline ones set everything
   EXCEPT case — so fixing them one at a time would be fixing them until the
   next one turns up. */
body[data-page="studio"] label { text-transform: none; letter-spacing: normal; }

.eltp-wrap{max-width:1280px;margin:0 auto;padding:22px 20px 60px}
/* .eltp-head and its h1 lived here. The strip they styled is gone — see the
   note where it used to be in index.php — and a rule matching nothing is a rule
   somebody later spends five minutes looking for the element of. */

/* The sheet size, now in the preview toolbar. margin-left:auto is what pushes
   it and the orientation beside it over to the right. */
.eltp-dims{margin-left:auto;font-size:12px;color:var(--muted)}
/* Was an inline style on the span. Moved here when the pair was made — two
   captions that sit together and read alike should not be styled in two
   different places. */
.eltp-orient{font-size:12px;color:var(--muted)}

/* THREE COLUMNS: controls, the sheet, the filing cabinet.
   The middle one is the only 1fr, so the sheet takes every pixel the other two
   do not — which is right, because it is the thing being looked at. */
.eltp-grid{display:grid;grid-template-columns:340px 1fr 272px;gap:22px;align-items:start}

/* TWO BREAKPOINTS, NOT ONE, because the two side columns are not equally
   negotiable. Below ~1240px the saved list is what gives — it is a thing you
   visit, while the controls are a thing you hold — so it drops to a full-width
   strip under the sheet rather than squeezing the preview to nothing. Only
   below 900px does the whole thing become one column. */
@media(max-width:1240px){
  .eltp-grid{grid-template-columns:340px 1fr}
  .eltp-posters{grid-column:1/-1}
  /* Lying on its side it has room to spread, so the saved posters go in a row
     of cards rather than a tall list nobody can see the bottom of. */
  .eltp-posters .eltp-poster-list{
    max-height:none;display:grid;gap:8px;
    grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  }
}
@media(max-width:900px){.eltp-grid{grid-template-columns:1fr}}

.eltp-panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--radius);padding:16px}
.eltp-panel.controls{max-height:calc(100vh - 170px);overflow-y:auto}

/* ───────────────────────────────────────────────────── the saved poster list
 *
 * THE SAME HEIGHT RULE AS THE CONTROLS. Both columns are sidebars next to a
 * tall sheet; letting either grow past the viewport is how you get a page with
 * two scrollbars that disagree about which one you meant to use.
 */
.eltp-posters{max-height:calc(100vh - 170px);overflow-y:auto}
.eltp-poster-list{margin-top:12px;display:flex;flex-direction:column;gap:8px}

.eltp-poster{
  display:flex;gap:9px;align-items:center;
  padding:7px;border:1px solid var(--line);border-radius:9px;
  background:rgba(255,255,255,.03);cursor:pointer;
  transition:background .15s,border-color .15s;
}
.eltp-poster:hover{background:rgba(255,255,255,.08);border-color:var(--accent)}
/* WHICH ONE IS OPEN, SAID ON THE ROW. Update writes over a specific poster, so
   the page has to be unambiguous about which one that is. */
.eltp-poster.on{border-color:var(--accent);background:rgba(98,255,176,.10)}

/* 3:4 — the sheet's own proportion, near enough. A square would crop the face
   out of a portrait poster, which is the one thing the thumbnail is for. */
.eltp-poster-shot{
  flex:none;width:42px;aspect-ratio:3/4;border-radius:5px;
  background:#fff center/cover no-repeat;border:1px solid var(--line);
}
.eltp-poster-shot.none{background:rgba(255,255,255,.05)}

.eltp-poster-main{flex:1;min-width:0}
/* min-width:0 above and the ellipsis here are one idea: a flex child refuses to
   shrink below its content by default, so a long name would push the buttons
   off the row instead of being truncated. */
.eltp-poster-main b{display:block;font-size:12px;font-weight:700;color:var(--head);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.eltp-poster-main span{display:block;font-size:10px;color:var(--muted)}

.eltp-poster-acts{flex:none;display:flex;gap:2px}
.eltp-poster-acts button{
  border:0;background:none;cursor:pointer;color:var(--muted);
  font-size:12px;line-height:1;padding:4px;border-radius:5px;font-family:inherit;
}
.eltp-poster-acts button:hover{background:rgba(255,255,255,.12);color:var(--head)}
.eltp-poster-acts button.danger:hover{background:rgba(255,97,120,.18);color:#ff9fae}

/* The name, being edited in place. Same box, so the row does not jump. */
.eltp-poster-main input{
  width:100%;font:700 12px inherit;font-family:inherit;
  background:var(--panel);color:var(--head);
  border:1px solid var(--accent);border-radius:5px;padding:2px 5px;
}

.eltp-section{margin-bottom:18px}
.eltp-section:last-child{margin-bottom:0}
.eltp-section .st{font-size:11px;text-transform:uppercase;letter-spacing:1.4px;color:var(--muted);font-weight:800;margin-bottom:9px}
.eltp-field{margin-bottom:11px}
/* THE LAST TWO PROPERTIES ARE NOT DECORATION, THEY ARE A REPAIR. base.css
   styles a bare <label> as a field caption — small, letter-spaced, UPPERCASE —
   which is right for the tools that grew that convention. This rule always set
   the size, colour and spacing it wanted but never mentioned case, so the
   moment this tool started loading base.css its labels began SHOUTING. A rule
   that overrides another has to name everything it cares about; the properties
   it leaves out are the ones that surprise you. */
.eltp-field label{display:block;font-size:12px;color:var(--text);margin-bottom:4px;
                  text-transform:none;letter-spacing:normal}
.eltp-field label .v{float:right;color:var(--accent);font-weight:700}

/* A note that belongs to a label rather than under the control. Quieter and a
   size down, so it reads as an aside to the heading beside it and does not
   compete with it — see where it is used above the nudge pad. */
.eltp-aside{font-size:11px;color:var(--muted);font-weight:400}
.eltp-field input[type=text],.eltp-field input[type=password],.eltp-field input[type=color],.eltp-field select{
    width:100%;padding:8px 10px;border-radius:8px;border:1px solid var(--line);
    background:rgba(0,0,0,.3);color:var(--head);font-size:13px;outline:none;font-family:inherit}
.eltp-field input[type=color]{height:38px;padding:3px 4px;cursor:pointer}

/* ─────────────────────────────── a text box with its colour on the end of it
 *
 * align-items:stretch IS WHAT MAKES THE SQUARE A SQUARE. The swatch is given a
 * width but no height: it takes the row's, which is the text box's, so the two
 * stay the same height if the field's padding or font size ever changes. A
 * hard-coded 38px here would be a number that drifts out of step the first time
 * anybody touches the input rule above.
 *
 * flex:1 AND min-width:0 ON THE TEXT BOX. The rule above gives every input
 * width:100%; inside a flex row that becomes a basis the box refuses to shrink
 * below, so a long placeholder would push the swatch out of the panel. */
.eltp-inrow{display:flex;gap:8px;align-items:stretch}
.eltp-inrow input[type=text]{flex:1;min-width:0}
.eltp-inrow input[type=color]{
  flex:none;width:38px;height:auto;padding:3px;
  /* The native swatch has its own inner inset. Trimming it makes the colour
     read as a filled square rather than a tiny chip in a box. */
}
.eltp-inrow input[type=color]::-webkit-color-swatch-wrapper{padding:0}
.eltp-inrow input[type=color]::-webkit-color-swatch{border:none;border-radius:5px}
.eltp-inrow input[type=color]::-moz-color-swatch{border:none;border-radius:5px}
.eltp-field input[type=range]{width:100%;accent-color:var(--accent)}
.eltp-field input:focus,.eltp-field select:focus{border-color:var(--accent)}

/* text-decoration:none BECAUSE ONE OF THESE IS AN <a>. The frame download is a
   real link to a real file — see the note beside it in index.php — and without
   this it would be the one button on the page wearing an underline. Harmless on
   the <button>s, which never had one. */
.eltp-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:9px 15px;border-radius:9px;cursor:pointer;
    font-size:13px;font-weight:700;border:1px solid var(--line);background:rgba(255,255,255,.06);color:var(--head);
    text-decoration:none;transition:background .15s,filter .15s;font-family:inherit}
/* The drop zone above it has no margin of its own, so the gap is set here
   rather than by wrapping the link in a spacer div. */
#frameDownload{margin-top:10px}
.eltp-btn:hover{background:rgba(255,255,255,.12)}
.eltp-btn.full{width:100%}
.eltp-btn.accent{background:var(--accent);border-color:var(--accent);color:#04121f}
.eltp-btn.accent:hover{filter:brightness(1.08)}
.eltp-btn.sm{padding:5px 9px;font-size:11px}

.eltp-drop{border:2px dashed var(--line);border-radius:11px;padding:20px 14px;text-align:center;
    cursor:pointer;transition:border-color .2s,background .2s;margin-bottom:9px}
.eltp-drop:hover,.eltp-drop.dragover{border-color:var(--accent);background:rgba(98,255,176,.07)}
.eltp-drop .ic{font-size:24px;margin-bottom:5px}
.eltp-drop .h{font-size:12px;color:var(--muted)}

.eltp-nudge{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;width:138px;margin:6px auto 2px}
.eltp-nudge .eltp-btn{padding:7px 0}
.eltp-nudge .c{display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;color:var(--muted);
    border:1px solid var(--line);border-radius:8px;cursor:pointer}

.eltp-hint{font-size:11px;color:var(--muted);line-height:1.45;margin-top:3px}

.eltp-stage-wrap{display:flex;align-items:flex-start;justify-content:center;overflow:auto;
    background:repeating-conic-gradient(rgba(255,255,255,.03) 0% 25%,transparent 0% 50%) 0 0/22px 22px;
    border-radius:var(--radius);padding:20px}
#eltp-stage{max-width:100%;height:auto;box-shadow:0 8px 44px rgba(0,0,0,.55);background:#fff;border-radius:2px}

.eltp-toolbar{display:flex;gap:10px;align-items:center;margin-bottom:12px;flex-wrap:wrap}
.eltp-saved{font-size:11px;font-weight:700;color:var(--accent);opacity:0;transition:opacity .25s}

.eltp-modal{position:fixed;inset:0;background:rgba(0,0,0,.75);display:none;align-items:center;justify-content:center;z-index:9998;padding:24px}
.eltp-modal.on{display:flex}
.eltp-modal-box{background:var(--bg2);border:1px solid var(--line);border-radius:14px;width:min(760px,100%);
    max-height:82vh;display:flex;flex-direction:column;overflow:hidden}
.eltp-modal-box.narrow{width:min(400px,100%)}
.eltp-modal-hd{padding:14px 18px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px;font-weight:700;color:var(--head)}
.eltp-modal-bd{padding:16px 18px;overflow-y:auto}
.eltp-picker{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:12px}
.eltp-pick{cursor:pointer;border:1px solid var(--line);border-radius:9px;overflow:hidden;background:rgba(0,0,0,.25);transition:border-color .15s,transform .15s}
.eltp-pick:hover{border-color:var(--accent);transform:translateY(-2px)}
.eltp-pick img{width:100%;height:120px;object-fit:cover;display:block;background:#222}
.eltp-pick .n{font-size:10px;padding:5px 6px;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

.eltp-loader{position:fixed;inset:0;background:rgba(0,0,0,.78);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:9999}
.eltp-loader.on{display:flex}
.eltp-loader .sp{width:46px;height:46px;border:4px solid rgba(255,255,255,.15);border-top-color:var(--accent);border-radius:50%;animation:eltpspin .8s linear infinite}
.eltp-loader .t{margin-top:14px;color:#fff;font-size:15px}
@keyframes eltpspin{to{transform:rotate(360deg)}}

.eltp-toasts{position:fixed;top:16px;right:16px;z-index:10000;display:flex;flex-direction:column;gap:8px;pointer-events:none}
.eltp-toast{padding:10px 16px;border-radius:9px;font-size:13px;font-weight:600;color:#04121f;box-shadow:0 6px 22px rgba(0,0,0,.4);pointer-events:auto}
.eltp-toast.info{background:#7cc4ff}.eltp-toast.success{background:var(--accent)}
.eltp-toast.error{background:var(--danger)}.eltp-toast.warn{background:var(--warn)}
