/* Application workspace (Releases AL, AO, AP): shared by in-browser tools (LT_APP_MODULES) and server tools
   (SA_APP_TOOLS) — step bar, working area, settings panel, phase-based phone layout. Loaded only on those tool pages. */
/* Release AL: the application workspace for in-browser tools listed in lt_app_modules (app/main.py). A step bar
   that follows the real phase (data-lt-phase, set by local-tool.js), a working area and a Settings panel. Desktop
   shows both side by side; phones show one phase at a time with the action kept above the tab bar. */
.tool-page-hero--app { padding-bottom: .4rem; }
.tool-page-hero--app .tool-h1 { font-size: clamp(1.55rem, 3vw, 2.35rem); margin-bottom: .35rem; }
.tool-page-hero--app .lead { font-size: .98rem; max-width: 62ch; }
.tool-page-hero--app .proc-badge { margin-top: .55rem; }
@media (max-width: 639px) {
  .tool-page-hero--app .lead { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .tool-page-hero--app .pill-hub, .tool-page-hero--app .proc-badge-text > span { display: none; }
}
.local-tool.lt-app { padding: 0; border-radius: 22px; overflow: visible; box-shadow: var(--ae-hi), 0 1px 2px #00000033, 0 18px 44px #0000004d; }
html[data-theme="light"] .local-tool.lt-app { box-shadow: var(--ae-hi), 0 1px 2px #1018280f, 0 18px 44px #10182814; }
.lt-app .lt-phases { list-style: none; margin: 0; padding: .7rem .9rem; display: flex; gap: .4rem; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--border); }
.lt-app .lt-phases::-webkit-scrollbar { display: none; }
.lt-app .lt-phases li { display: inline-flex; align-items: center; gap: .45rem; padding: .3rem .8rem .3rem .35rem; border-radius: 999px; font-size: .82rem; font-weight: 650; color: var(--muted); white-space: nowrap; transition: background-color var(--ae-med), color var(--ae-med); }
.lt-ph-n { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: .72rem; font-weight: 800; background: color-mix(in srgb, var(--text) 9%, transparent); transition: background-color var(--ae-med), color var(--ae-med); }
.lt-app[data-lt-phase="empty"] li[data-p="empty"], .lt-app[data-lt-phase="ready"] li[data-p="ready"], .lt-app[data-lt-phase="working"] li[data-p="ready"], .lt-app[data-lt-phase="done"] li[data-p="done"] { color: var(--text); background: color-mix(in srgb, var(--brand) 14%, transparent); }
.lt-app[data-lt-phase="empty"] li[data-p="empty"] .lt-ph-n, .lt-app[data-lt-phase="ready"] li[data-p="ready"] .lt-ph-n, .lt-app[data-lt-phase="working"] li[data-p="ready"] .lt-ph-n, .lt-app[data-lt-phase="done"] li[data-p="done"] .lt-ph-n { background: var(--brand); color: var(--on-brand); }
.lt-app[data-lt-phase="ready"] li[data-p="empty"] .lt-ph-n, .lt-app[data-lt-phase="working"] li[data-p="empty"] .lt-ph-n, .lt-app[data-lt-phase="done"] li:not([data-p="done"]) .lt-ph-n { background: color-mix(in srgb, var(--brand) 32%, transparent); color: var(--text); }
.lt-app-body { display: grid; }
.lt-main { min-width: 0; padding: clamp(1rem, 2.4vw, 1.5rem); display: grid; gap: 1rem; align-content: start; }
.lt-side { min-width: 0; padding: clamp(1rem, 2.4vw, 1.5rem); display: grid; gap: 1rem; align-content: start; border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface-solid) 72%, var(--bg)); border-radius: 0 0 22px 22px; }
@media (min-width: 1024px) {
  .lt-app-body { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); }
  .lt-side { border-top: 0; border-left: 1px solid var(--border); border-radius: 0 0 22px 0; }
  .lt-app .lt-actions { position: sticky; bottom: 1rem; }
}
@media (min-width: 1600px) { .lt-app-body { grid-template-columns: minmax(0, 1fr) minmax(340px, 420px); } }
.lt-side-title { margin: 0; font-size: .76rem; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.lt-app .lt-options { margin: 0; padding: 0; border: 0; min-width: 0; }
.lt-app .lt-actions { margin: 0; display: grid; gap: .5rem; }
.lt-app .lt-actions .btn-primary { width: 100%; justify-content: center; }
/* Working area */
.lt-app .lt-drop { margin: 0; min-height: clamp(220px, 34vw, 360px); display: grid; place-items: center; border-radius: 18px; }
.lt-app:not(.lt-multi):not([data-lt-phase="empty"]) .lt-drop { display: none; }
.lt-app.lt-multi:not([data-lt-phase="empty"]) .lt-drop { min-height: 0; padding: .9rem; }
.lt-app.lt-multi:not([data-lt-phase="empty"]) .lt-drop .upload-zone-icon, .lt-app.lt-multi:not([data-lt-phase="empty"]) .lt-drop .lt-stays { display: none; }
.lt-app.lt-multi .lt-pick { display: none; }
.lt-app .lt-file { margin: 0; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: .9rem; padding: .85rem; border-radius: 18px;
  border: 1px solid var(--border); background: var(--surface-solid); box-shadow: var(--ae-hi), 0 1px 2px #00000029; }
.lt-app .lt-file.hidden { display: none; }
.lt-app .lt-thumb { width: 72px; height: 72px; object-fit: cover; border-radius: 14px; border: 1px solid var(--border); background: var(--bg); grid-row: span 2; }
.lt-app .lt-thumb[hidden] { display: none; }
.lt-app .lt-file-row { margin: 0; display: grid; gap: .15rem; min-width: 0; }
.lt-app .lt-file-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lt-app .lt-file-size { color: var(--muted); font-size: .85rem; }
.lt-app .lt-output { margin: 0; grid-column: 2; color: var(--link); font-size: .85rem; font-weight: 600; }
.lt-app .lt-pick { grid-column: 3; grid-row: 1 / span 2; white-space: nowrap; }
.lt-app .lt-estimate { margin: 0; padding: .65rem .85rem; border-radius: 12px; background: color-mix(in srgb, var(--brand) 9%, transparent); color: var(--text); font-size: .88rem; }
.lt-app .lt-progress { margin: 0; padding: 1.25rem; border-radius: 18px; border: 1px solid var(--border); background: var(--surface-solid); }
.lt-app .lt-result { margin: 0; display: grid; gap: .85rem; padding: clamp(.9rem, 2vw, 1.25rem); border-radius: 18px; border: 1px solid color-mix(in srgb, var(--brand) 35%, var(--border));
  background: linear-gradient(180deg, color-mix(in srgb, var(--brand) 7%, var(--surface-solid)), var(--surface-solid)); box-shadow: var(--ae-hi), 0 10px 26px #00000033; }
.lt-app .lt-result.hidden { display: none; }
.lt-app .lt-image:not(.hidden) { display: block; width: 100%; max-height: min(56vh, 460px); object-fit: contain; border-radius: 14px;
  background-color: #e5e7eb; background-image: linear-gradient(45deg, #cbd2db 25%, transparent 25%, transparent 75%, #cbd2db 75%), linear-gradient(45deg, #cbd2db 25%, transparent 25%, transparent 75%, #cbd2db 75%);
  background-size: 18px 18px; background-position: 0 0, 9px 9px; }
.lt-app .lt-note { margin: 0; font-weight: 700; color: var(--link); }
.lt-app .lt-result-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.lt-app .lt-result-actions .download-btn { flex: 1 1 14rem; justify-content: center; }
/* Phones and tablets: one phase at a time; the action stays reachable above the floating tab bar. */
@media (max-width: 1023px) {
  .lt-app[data-lt-phase="empty"] .lt-side, .lt-app[data-lt-phase="working"] .lt-side, .lt-app[data-lt-phase="done"] .lt-side { display: none; }
  .lt-app[data-lt-phase="ready"] .lt-actions, .lt-app[data-lt-phase="done"] .lt-result-actions {
    position: sticky; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); z-index: 6; padding: .6rem; margin: 0 -.35rem; border-radius: 18px;
    border: 1px solid var(--border); background: color-mix(in srgb, var(--surface-solid) 94%, var(--bg)); box-shadow: 0 10px 28px #00000059; }
}
@media (max-width: 768px) {
  .lt-app[data-lt-phase="ready"] .lt-actions, .lt-app[data-lt-phase="done"] .lt-result-actions { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 400px) { .lt-app .lt-file { grid-template-columns: auto minmax(0, 1fr); } .lt-app .lt-pick { grid-column: 1 / -1; grid-row: auto; } }
@media (prefers-reduced-motion: reduce) { .lt-app .lt-phases li, .lt-ph-n { transition: none; } }

/* Release AL: the form-memory bar sits in the workspace toolbar row, beside the step bar; on desktop the loaded image
   is shown large in the working area. */
.local-tool.lt-app { display: grid; grid-template-columns: minmax(0, 1fr) auto; }
.local-tool.lt-app > * { grid-column: 1 / -1; }
.local-tool.lt-app > .lt-phases { grid-column: 1; }
.local-tool.lt-app > .fm-bar { grid-column: 2; margin: 0; padding: .45rem .9rem .45rem .4rem; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; background: transparent; box-shadow: none; align-self: stretch; display: flex; align-items: center; }
/* Phones too: the bar stays in the step-bar row (it is added after load; a row of its own pushed the workspace down,
   CLS 0.038). The steps scroll sideways if needed; the save status is read out but not shown (its dot still is). */
@media (max-width: 639px) {
  .local-tool.lt-app > .fm-bar { grid-column: 2; padding: .35rem .6rem .35rem 0; gap: .3rem; }
  .local-tool.lt-app > .fm-bar .fm-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .local-tool.lt-app > .fm-bar .fm-btn { min-height: 36px; padding: .3rem .55rem; font-size: .76rem; }
  .local-tool.lt-app > .lt-phases { padding-right: .4rem; }
}
@media (min-width: 1024px) {
  .lt-app:not(.lt-multi) .lt-file { grid-template-columns: minmax(0, 1fr) auto; }
  .lt-app:not(.lt-multi) .lt-thumb { grid-column: 1 / -1; grid-row: auto; width: 100%; height: auto; max-height: min(52vh, 420px); object-fit: contain;
    background-color: #e5e7eb; background-image: linear-gradient(45deg, #cbd2db 25%, transparent 25%, transparent 75%, #cbd2db 75%), linear-gradient(45deg, #cbd2db 25%, transparent 25%, transparent 75%, #cbd2db 75%);
    background-size: 18px 18px; background-position: 0 0, 9px 9px; }
  .lt-app:not(.lt-multi) .lt-file-row, .lt-app:not(.lt-multi) .lt-output { grid-column: 1; }
  .lt-app:not(.lt-multi) .lt-pick { grid-column: 2; grid-row: 2 / span 2; }
}

/* The chat button never sits on the workspace's sticky action (desktop): it moves up while an app workspace is on the page. */
@media (min-width: 769px) { body:has(.lt-app) .chat-fab:not(.is-placed) { bottom: 6.5rem; } }

/* While the on-screen keyboard is open the field being typed in has priority: the action bar goes back into the flow. */
body.kbd-open .lt-app .lt-actions, body.kbd-open .lt-app .lt-result-actions { position: static; box-shadow: none; }

/* Release AO: tools whose own editor needs the full width (Photo Print Sheet: photos, sheet settings, live sheet preview)
   stack the settings under the working area; batch queues sit in the working area (moved there by local-tool.js). */
@media (min-width: 1024px) {
  .lt-app--stack .lt-app-body { grid-template-columns: minmax(0, 1fr); }
  .lt-app--stack .lt-side { border-left: 0; border-top: 1px solid var(--border); border-radius: 0 0 22px 22px; }
  .lt-app--stack .lt-actions { max-width: 26rem; margin-left: auto; }
}
.lt-app--stack.lt-multi:not([data-lt-phase="empty"]) .lt-drop { display: none; }
.lt-app .lt-main > .lt-clips-wrap { margin: 0; padding: .85rem; border-radius: 18px; border: 1px solid var(--border); background: var(--surface-solid); box-shadow: var(--ae-hi), 0 1px 2px #00000029; }
.lt-app .lt-main > .lt-clips-wrap .lt-clips { max-height: min(48vh, 520px); overflow: auto; }

/* Stacked workspaces: the sticky action is a solid bar of its own (it never floats over the sheet preview). */
@media (min-width: 1024px) {
  .lt-app--stack .lt-actions { max-width: none; margin: 0 -.25rem; padding: .7rem; display: flex; justify-content: flex-end; gap: .5rem; border-radius: 18px;
    border: 1px solid var(--border); background: color-mix(in srgb, var(--surface-solid) 96%, var(--bg)); box-shadow: 0 -8px 24px #00000040; z-index: 6; }
  .lt-app--stack .lt-actions .btn-primary { width: auto; min-width: 16rem; }
}

/* Release AP: server tool workspace (PDF Compress). Real upload progress, then an honest "processing" state; the final
   result card with the measured sizes, the private download and when the server deletes the file. */
.sa-app #file-picked { display: none; }
.sa-app .sa-note { margin: .75rem auto 0; max-width: 34rem; color: var(--link); font-size: .85rem; font-weight: 600; }
.sa-file-ico { width: 56px; height: 56px; border-radius: 14px; display: grid; place-items: center; font-size: .78rem; font-weight: 800; letter-spacing: .04em; color: #fff;
  background: linear-gradient(180deg, #ffffff40, #fff0 50%), linear-gradient(145deg, #ef4444, #b91c1c); box-shadow: inset 0 1px 0 #ffffff59, inset 0 -3px 0 #0003, 0 6px 14px #b91c1c40; grid-row: span 2; }
.sa-progress .progress-track { height: 10px; border-radius: 999px; background: color-mix(in srgb, var(--text) 10%, transparent); overflow: hidden; }
.sa-progress .progress-fill { height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, var(--brand2), var(--brand)); transition: width .2s linear; }
.sa-app.sa-processing .sa-progress .progress-fill { width: 35%; animation: sa-ind 1.3s ease-in-out infinite; }
@keyframes sa-ind { from { transform: translateX(-110%); } to { transform: translateX(300%); } }
.sa-progress-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-top: .8rem; }
.sa-progress-row p { margin: 0; font-weight: 650; }
.sa-results:empty { display: none; }
.sa-result-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; }
.sa-result-title { margin: 0; font-size: 1.15rem; letter-spacing: -.01em; }
.sa-badge { padding: .25rem .75rem; border-radius: 999px; font-size: .85rem; font-weight: 800; background: var(--brand); color: var(--on-brand); box-shadow: var(--ae-hi); }
.sa-warn { margin: 0; padding: .75rem .9rem; border-radius: 12px; border: 1px solid #f59e0b66; background: #f59e0b1f; color: var(--text); font-weight: 600; }
.sa-stats { width: 100%; border-collapse: collapse; font-size: .92rem; }
.sa-stats th, .sa-stats td { padding: .5rem .25rem; border-bottom: 1px solid var(--border); }
.sa-stats th { text-align: left; color: var(--muted); font-weight: 600; }
.sa-stats td { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.sa-facts { margin: 0; padding-left: 1.1rem; display: grid; gap: .3rem; color: var(--muted); font-size: .88rem; }
.sa-facts .is-warn { color: #d97706; }
.sa-expiry { margin: 0; color: var(--muted); font-size: .84rem; }
.sa-app .tool-error:empty { display: none; }
@media (prefers-reduced-motion: reduce) { .sa-app.sa-processing .sa-progress .progress-fill { animation: none; width: 100%; opacity: .6; } .sa-progress .progress-fill { transition: none; } }

/* Server workspace: settings fill the side column (the generic server-tool field widths would overflow it), and the
   file card keeps its icon beside the name on every width. */
.lt-app.sa-app .lt-side .tool-fields { margin: 0; padding: 0; border: 0; background: none; box-shadow: none; display: grid; gap: .85rem; }
.lt-app.sa-app .lt-side .control-row { display: grid; gap: .4rem; margin: 0; min-width: 0; }
.lt-app.sa-app .lt-side .control-row > label { font-weight: 650; font-size: .88rem; }
.lt-app.sa-app .lt-side select, .lt-app.sa-app .lt-side input[type="number"] { width: 100%; max-width: 100%; min-width: 0; box-sizing: border-box; }
.lt-app.sa-app .lt-side .pdfc-target-pair { display: grid; grid-template-columns: minmax(0, 1fr) 5.5rem; gap: .5rem; }
.lt-app.sa-app .lt-side .pdfc-check-row { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
.lt-app.sa-app .lt-side .field-hint { margin: 0; font-size: .82rem; color: var(--muted); line-height: 1.5; }
.lt-app.sa-app .lt-side .tool-run-row { margin: 0; }
.lt-app.sa-app .lt-side .tool-run-row .btn-primary { width: 100%; }
.lt-app.sa-app .lt-file { grid-template-columns: auto minmax(0, 1fr) auto; }
.lt-app.sa-app .lt-file-row { grid-column: 2; }
.lt-app.sa-app .lt-pick { grid-column: 3; grid-row: 1 / span 2; }
@media (max-width: 400px) { .lt-app.sa-app .lt-file { grid-template-columns: auto minmax(0, 1fr); } .lt-app.sa-app .lt-pick { grid-column: 1 / -1; grid-row: auto; } }

/* Mid-size desktops: the floating chat button would sit on the workspace's settings panel, so on workspace pages it
   gives way to the "Ask AI" chip in the tool header. Wider screens keep it (there is room beside the workspace). */
@media (min-width: 769px) and (max-width: 1519px) { body:has(.lt-app) .chat-fab:not(.is-open) { display: none; } }
@media (max-width: 768px), (min-width: 1520px) { .chat-chip-open { display: none; } }

/* Phones: the current step shows its label, the others only their number (they fit beside New / Clear form). */
@media (max-width: 639px) {
  .lt-app .lt-phases li { font-size: 0; gap: 0; padding: .3rem; }
  .lt-app .lt-phases li .lt-ph-n { font-size: .72rem; }
  .lt-app[data-lt-phase="empty"] li[data-p="empty"], .lt-app[data-lt-phase="ready"] li[data-p="ready"],
  .lt-app[data-lt-phase="working"] li[data-p="ready"], .lt-app[data-lt-phase="done"] li[data-p="done"] { font-size: .8rem; gap: .4rem; padding: .3rem .7rem .3rem .3rem; }
}
