/* Refinery on the park guide map. Tokens, the lobe, capsules, the level bar and the result panel come from
   shared/theme.css. Here: the block palette, the pipeline (stations joined by one ink path that the rows travel as
   dots), the toolbar, and the cream lakes that hold the tables. Coral marks only what is not solved or wrong. */
.tables > * { min-width: 0; } /* lets inner scrollers scroll instead of widening the page */
.muted { color: var(--muted); }

#title:focus { outline: none; } /* focused after Next level, so reading resumes at the top of the new level */
#goal { margin: 8px 0 0; font-size: 17px; line-height: 1.45; max-width: 60ch; }

/* ---- blocks to pick from ---- */
.tools { display: grid; gap: 16px; min-width: 0; }
.tools > * { min-width: 0; }
#palette { display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center; }
.pal-label { font: 800 19px/1 var(--display); letter-spacing: -.02em; margin-right: 6px; }
.pal {
  display: grid; align-content: center; text-align: left; cursor: pointer; min-height: 56px; padding: 7px 16px;
  font: 700 16px/1.25 var(--font); color: var(--ink); background: var(--water);
  border: 2px solid var(--ink); border-radius: var(--radius-card);
  transition: transform var(--t) var(--bounce), background-color .2s;
}
.pal:hover { transform: translateY(-2px); background: var(--panel-2); }
.pal:active { transform: scale(.96); }
.pal small { font: 400 14px/1.25 var(--font); }

/* ---- the pipeline: Input, blocks and Output are stations; game.js draws the path between them ---- */
.lane { position: relative; isolation: isolate; display: flex; flex-wrap: wrap; align-items: center; gap: 44px 112px; padding: 12px 0; min-height: 108px; }
.lane > * { flex: none; }
.lane:focus { outline: none; } /* only focused as a fallback when a rebuilt control is gone */
.route { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.route svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.route path { fill: none; stroke: var(--ink); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.route .planned path { stroke-dasharray: 1 9; } /* no blocks yet: the route is only planned */
/* a row: a dot resting on the stretch of path it has travelled */
.token { position: absolute; left: 0; top: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--ink); offset-rotate: 0deg; }
.token.go { animation: travel var(--t) var(--bounce) both; }
@keyframes travel { from { offset-distance: 0%; opacity: 0; } 25% { opacity: 1; } to { offset-distance: var(--at); } }

.node { display: grid; align-content: center; gap: 4px; min-height: 76px; padding: 10px 22px; font-size: 15px; background: var(--water); border: 2px solid var(--ink); border-radius: 38px; }
.node b { font: 800 20px/1 var(--display); letter-spacing: -.02em; }
.node.out { min-width: 176px; margin-left: auto; border-radius: 26px; justify-items: start; }
.node.out.solo { margin-left: 0; }
.empty { flex: 0 1 280px; padding: 12px 18px; font-size: 15px; line-height: 1.35; background: var(--water); border: 2px dashed var(--ink); border-radius: var(--radius-card); }

.block {
  width: 288px; padding: 12px 14px 14px; background: var(--water); border: 2px solid var(--ink); border-radius: var(--radius-card);
  transition: transform var(--t) var(--bounce), background-color .2s;
  scroll-margin-block: 12px;
}
.block.working { background: var(--panel-2); transform: scale(1.03); } /* the rows have arrived here */
.block.error { animation: shake .4s; }
@keyframes shake { 25% { transform: translateX(-6px); } 50% { transform: translateX(6px); } 75% { transform: translateX(-3px); } }
.block header { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; cursor: grab; }
.block header b { margin-right: auto; font: 800 19px/1 var(--display); letter-spacing: -.02em; }
/* round icon buttons; the arrow text stays in the markup, the drawn icon covers it */
.ctl {
  position: relative; flex: none; width: 32px; height: 32px; padding: 0; cursor: pointer; font-size: 0;
  color: var(--ink); background: var(--water); border: 2px solid var(--ink); border-radius: 50%;
  transition: transform var(--t) var(--bounce), background-color .2s, color .2s;
}
.ctl::before { content: ''; position: absolute; inset: 6px; background: currentColor; mask: var(--i-x) center / contain no-repeat; }
.ctl[data-testid$="move-left"]::before { mask-image: var(--i-prev); }
.ctl[data-testid$="move-right"]::before { mask-image: var(--i-next); }
.ctl:hover { background: var(--ink); color: var(--water); }
.ctl:active { transform: scale(.9); }
.ctl[aria-disabled="true"] { color: var(--muted); border-color: var(--muted); border-style: dashed; background: var(--water); transform: none; cursor: default; }
.fields { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 12px; }
.fields label { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; align-items: center; font: 600 14px/1.2 var(--font); }
.fields select, .fields input {
  width: 100%; min-width: 0; height: 34px; padding: 0 6px; font: 13px var(--mono); color: var(--ink);
  background: var(--water); border: 2px solid var(--ink); border-radius: 10px;
}
.fields select:hover, .fields input:hover { background: var(--panel-2); }
.fields input::placeholder { color: var(--muted); opacity: 1; }
.block footer { margin-top: 12px; font: 12px var(--mono); }
.block footer.err { display: flex; gap: 6px; align-items: baseline; padding: 7px 10px; border-radius: 10px; background: var(--coral); font: 600 13px/1.35 var(--font); }
.block footer.err .ico { align-self: center; }
/* rows in → rows out; a button, because it opens the table at this block */
.count {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; width: 100%; min-height: 34px; padding: 4px 10px;
  font: inherit; color: var(--ink); cursor: pointer; text-align: left;
  background: var(--panel-2); border: 2px solid var(--ink); border-radius: 10px;
}
.count:hover { background: var(--water); }
.count b { font-size: 14px; }
.peek { margin-left: auto; font: 700 13px/1 var(--font); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; white-space: nowrap; }
.note { margin: 8px 0 0; font: 13px/1.4 var(--font); }
.note.fanout, .note.nomatch { color: var(--amber); font-weight: 600; }
.block.warn .count b.more { font-size: 15px; color: var(--amber); }
.fresh footer { animation: pop var(--t) var(--bounce) both; }
@keyframes pop { from { transform: scale(.6); opacity: 0; } }

/* ---- toolbar: the target, Reset and the one Run capsule ---- */
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.actions .target-chip { margin-right: auto; }
.run-why { flex-basis: 100%; margin: 0; text-align: right; font-size: 14px; font-weight: 600; }
.run-why:empty { display: none; }

/* ---- lakes: what you have → what you need, and after a run your output against the target ---- */
.compare h2 { font-size: 19px; margin: 0 0 10px; }
.compare .btn { margin-top: 14px; }
.data-strip > summary { cursor: pointer; list-style: none; display: flex; flex-wrap: wrap; gap: 2px 10px; align-items: center; min-height: 28px; }
.data-strip > summary::-webkit-details-marker { display: none; }
.data-strip > summary::before { content: ''; flex: none; width: 16px; height: 16px; background: currentColor; mask: var(--i-down) center / contain no-repeat; transform: rotate(-90deg); transition: transform var(--t) var(--bounce); }
.data-strip[open] > summary::before { transform: none; }
.data-label { font: 700 14px/1 var(--font); white-space: nowrap; }
.delta { font: 13px/1.5 var(--mono); color: var(--muted); overflow-wrap: anywhere; min-width: 0; }
.delta b { font-family: var(--font); color: var(--ink); }
.delta:empty { display: none; }
/* Input and any lookup tables stack on the left, Target sits to their right; Target drops below when they cannot share a row */
.tables { display: flex; flex-wrap: wrap; gap: 14px 20px; align-items: flex-start; padding-top: 10px; }
.tables > * { max-width: 100%; }
.tables .have { display: grid; gap: 16px; }
.tables .have > * { min-width: 0; }
.tables .want { display: flex; gap: 20px; align-items: center; } /* the arrow travels with Target when it wraps */
.tables .want > div { min-width: 0; }
.tables .to { flex: none; font-size: 26px; }
.tables h2 { margin: 0 0 8px; font-size: 19px; }

/* A table wider than its lake scrolls sideways; an ink edge marks the side that hides more. */
.scroll {
  overflow-x: auto; scrollbar-width: thin;
  background:
    linear-gradient(var(--water) 0 0) left / 5px 100% no-repeat local,
    linear-gradient(var(--water) 0 0) right / 5px 100% no-repeat local,
    linear-gradient(var(--ink) 0 0) left / 3px 100% no-repeat scroll,
    linear-gradient(var(--ink) 0 0) right / 3px 100% no-repeat scroll;
}
table.data { white-space: nowrap; }
table.data th, table.data td { padding: 3px 16px 3px 0; }
table.data thead th { padding-bottom: 5px; vertical-align: top; }
table.data tr > :last-child { padding-right: 4px; }
table.data .type { display: block; font: 500 12px/1.3 var(--font); color: var(--muted); }
table.data td small { display: block; color: var(--muted); font-size: 11px; }
table.data td.err { padding-left: 6px; box-shadow: -6px 0 0 var(--coral); } /* the coral reaches back over the cell gap */
table.data td.err small { color: var(--ink); }
table.data th.err { color: var(--bad); }
table.data thead th.err small:not(.type) { display: block; font: 600 11px var(--font); } /* "missing" / "not in target" under the column name */
td.nocol { color: var(--muted); } /* a cell in a missing or extra column: a column problem, not a wrong value */
/* compared output: the first column says what each row is */
table.data tbody th { font: 600 12px var(--font); color: var(--bad); border-bottom: 1px solid var(--line); }
table.data tr.clean th { color: var(--good); font-size: 15px; }
table.data tr.extra td { color: var(--muted); text-decoration: line-through; }
table.data tr.missing td { color: var(--muted); font-style: italic; }

/* ---- result, on the water ---- */
#outPanel { isolation: isolate; }
#verdict .summary { font: 13px/1.5 var(--mono); }
#verdict .warn { color: var(--amber); font-weight: 600; }
#verdict > p:last-child { margin: 0; }
.confetti { position: absolute; left: 50%; top: 60px; pointer-events: none; z-index: -1; } /* behind the result text */
.confetti i { position: absolute; width: 9px; height: 9px; border-radius: 50%; background: var(--ink); animation: burst 1s ease-out both; } /* the rows, let go */
@keyframes burst { to { transform: translate(var(--dx), var(--dy)); opacity: 0; } }

@media (max-width: 640px) {
  /* the lane runs top to bottom, every station as wide as the screen; the path crosses over between them */
  .lane { flex-direction: column; align-items: stretch; gap: 48px; }
  .node, .node.out { min-height: 56px; margin: 0; grid-template-columns: auto 1fr; align-items: center; gap: 12px; }
  .empty { flex-basis: auto; }
  .block { width: auto; }
  .ctl[data-testid$="move-left"]::before, .ctl[data-testid$="move-right"]::before { transform: rotate(90deg); } /* up and down */
  .tables .to { display: none; }
  /* touch targets */
  .ctl { width: 44px; height: 44px; }
  .ctl::before { inset: 11px; }
  .pal, .count { min-height: 44px; } /* .btn and topbar targets come from theme.css */
  .pal { border-radius: 22px; }
  .fields select, .fields input { height: 44px; font-size: 16px; } /* 16px also stops iOS zooming on focus */
  .data-strip > summary { min-height: 44px; }
  .actions { justify-content: flex-end; }
  .tables .have { width: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .confetti { display: none; }
  .block.working { transform: none; }
}
