/* BoatLink demo UI — the boatlink.fi identity, worn by an application.
 *
 * One deliberate theme. The marketing site is night-watch dark with brass, and
 * an app that shares its name should feel like the same room - so every colour
 * is painted explicitly and there is no light variant to drift out of step.
 *
 * Type does the talking: Georgia for names and numerals (the same face as the
 * BL monogram), the system face for prose, and the platform mono for data,
 * because a bilge voltage is data and should look like it.
 */

/* An author `display` beats the browser's rule for [hidden], so a flex row that
   the script has hidden stays on screen - the weather line held its space with
   nothing in it whenever a boat had no position. Hidden means hidden. */
[hidden] { display: none !important; }

:root {
	--ground: #07090b;
	--panel: #0e1216;
	--raised: #141a1f;
	--sunken: #0a0d10;
	--line: #1d252c;
	--brass-line: rgba(201, 149, 72, .22);
	--ink: #eae5da;
	--dim: #8fa0aa;
	--faint: #5b6a73;
	--brass: #c99548;
	--brass-bright: #e3b878;
	--ok: #46c896;
	--warn: #e0a33d;
	--crit: #ef8078;
	--crit-wash: rgba(239, 128, 120, .1);
	--ok-wash: rgba(70, 200, 150, .08);
	--shadow: 0 1px 0 rgba(255, 255, 255, .03) inset, 0 10px 30px rgba(0, 0, 0, .45);

	--serif: Georgia, 'Iowan Old Style', 'Times New Roman', serif;
	--sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
	--mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
html { scrollbar-color: #2a343c var(--ground); }

body {
	background:
		radial-gradient(1200px 500px at 70% -10%, rgba(201, 149, 72, .05), transparent 60%),
		var(--ground);
	color: var(--ink);
	font: 15px/1.55 var(--sans);
	-webkit-font-smoothing: antialiased;
}

a { color: var(--brass); text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
button:focus-visible, a:focus-visible, input:focus-visible {
	outline: 2px solid var(--brass);
	outline-offset: 2px;
	border-radius: 4px;
}

/* ---- the recurring voices ---- */

.kicker {
	font: 600 10.5px/1 var(--mono);
	letter-spacing: .22em;
	text-transform: uppercase;
	color: var(--brass);
}
.kicker .n { color: var(--faint); }

.microlabel {
	font: 600 10px/1.3 var(--mono);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--faint);
}

.serif { font-family: var(--serif); }

/* ---- boot ---- */

.boot { min-height: 100dvh; display: grid; place-content: center; justify-items: center; gap: 18px; }
.boot-word { color: var(--faint); font-family: var(--mono); font-size: 12px; letter-spacing: .2em; text-transform: uppercase; }

.monogram {
	width: 54px; height: 54px;
	border: 1px solid var(--brass-line);
	border-radius: 14px;
	display: grid; place-content: center;
	font: 24px var(--serif);
	color: var(--brass);
	background: linear-gradient(180deg, rgba(201,149,72,.08), transparent);
}
.monogram.sm { width: 38px; height: 38px; font-size: 17px; border-radius: 10px; }

/* ---- login ---- */

.login {
	min-height: 100dvh;
	display: grid; place-content: center; justify-items: center;
	gap: 26px;
	padding: 24px;
	position: relative;
	overflow: hidden;
}
/* The radar-ring motif from boatlink.fi, at anchor: slow concentric brass
   rings breathing behind the card. */
.login::before {
	content: '';
	position: absolute; inset: -40%;
	background: repeating-radial-gradient(circle at 50% 58%,
		transparent 0 118px,
		rgba(201, 149, 72, .05) 118px 120px);
	animation: sweep 14s ease-in-out infinite;
	pointer-events: none;
}
@keyframes sweep {
	0%, 100% { transform: scale(1); opacity: .7; }
	50% { transform: scale(1.12); opacity: 1; }
}
.login > * { position: relative; }
.login-card {
	width: min(94vw, 380px);
	background: var(--panel);
	border: 1px solid var(--brass-line);
	border-radius: 16px;
	padding: 30px 28px 26px;
	box-shadow: var(--shadow);
	display: grid; gap: 16px;
}
.login h1 {
	margin: 0;
	font: 400 30px/1.1 var(--serif);
	letter-spacing: -.01em;
	text-wrap: balance;
}
.login .sub { margin: -6px 0 6px; color: var(--dim); font-size: 13.5px; }
.field { display: grid; gap: 6px; }
.field input {
	background: var(--sunken);
	border: 1px solid var(--line);
	border-radius: 9px;
	color: var(--ink);
	padding: 11px 13px;
	font-size: 15px;
}
.field input:focus { border-color: var(--brass); outline: none; }
.login-err { color: var(--crit); font-size: 13px; min-height: 18px; margin: 0; }

.btn-brass {
	background: linear-gradient(180deg, var(--brass-bright), var(--brass));
	color: #14100a;
	font-weight: 650;
	border-radius: 10px;
	padding: 12px 16px;
	text-align: center;
	letter-spacing: .02em;
}
.btn-brass:disabled { opacity: .55; cursor: default; }
.btn-quiet {
	border: 1px solid var(--line);
	border-radius: 10px;
	padding: 9px 14px;
	color: var(--dim);
}
.btn-quiet:hover { border-color: var(--brass-line); color: var(--ink); }

/* ---- app frame: rail on desktop, bars on mobile ---- */

.frame { min-height: 100dvh; display: grid; grid-template-columns: 218px 1fr; }

.rail {
	border-right: 1px solid var(--line);
	padding: 22px 16px calc(18px + env(safe-area-inset-bottom));
	display: flex; flex-direction: column; gap: 26px;
	position: sticky; top: 0; height: 100dvh;
	background: linear-gradient(180deg, rgba(201,149,72,.03), transparent 30%);
}
.rail-brand { display: flex; align-items: center; gap: 12px; }
.rail-brand .word { font: 600 13px/1.2 var(--mono); letter-spacing: .3em; }
.rail-brand .word small { display: block; color: var(--faint); font-size: 8.5px; letter-spacing: .28em; font-weight: 500; }

.rail nav { display: grid; gap: 4px; }
.rail nav a {
	display: flex; align-items: center; gap: 11px;
	padding: 10px 12px;
	border-radius: 9px;
	color: var(--dim);
	font-size: 14px;
}
.rail nav a svg { width: 17px; height: 17px; flex: none; }
.rail nav a.on { color: var(--ink); background: var(--raised); box-shadow: inset 2px 0 0 var(--brass); }
.rail nav a:hover { color: var(--ink); }
.rail .foot { margin-top: auto; display: grid; gap: 10px; }
.rail .foot .btn-quiet { display: flex; align-items: center; gap: 9px; font-size: 13px; }
.rail .foot svg { width: 15px; height: 15px; flex: none; }
.rail .who { color: var(--faint); font-size: 12px; overflow: hidden; text-overflow: ellipsis; }

.main { min-width: 0; padding: 26px clamp(16px, 4vw, 44px) 90px; }
.main-inner { max-width: 1180px; margin: 0 auto; display: grid; gap: 22px; }

/* Every view paints fresh elements, so insertion is the transition: each
   block rises in, slightly staggered, and tab panes do the same. */
.main-inner > *, #tabpane > * {
	animation: viewin .3s cubic-bezier(.2, .7, .3, 1) both;
}
.main-inner > *:nth-child(2) { animation-delay: .04s; }
.main-inner > *:nth-child(3) { animation-delay: .08s; }
.main-inner > *:nth-child(4) { animation-delay: .12s; }
@keyframes viewin { from { opacity: 0; transform: translateY(10px); } }

.appbar, .tabbar { display: none; }

@media (max-width: 880px) {
	.frame { grid-template-columns: 1fr; }
	.rail { display: none; }
	.main { padding: 14px 14px calc(84px + env(safe-area-inset-bottom)); }

	.appbar {
		display: flex; align-items: center; gap: 12px;
		position: sticky; top: 0; z-index: 60;
		margin: -14px -14px 12px;
		padding: calc(10px + env(safe-area-inset-top)) 16px 10px;
		background: rgba(7, 9, 11, .88);
		backdrop-filter: blur(14px);
		border-bottom: 1px solid var(--line);
	}
	.appbar .title { font: 400 17px var(--serif); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
	.appbar .back { color: var(--brass); font-size: 20px; padding: 4px 8px 4px 0; }

	.tabbar {
		display: grid; grid-auto-flow: column; justify-content: space-around;
		position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
		padding: 8px 6px calc(8px + env(safe-area-inset-bottom));
		background: rgba(10, 13, 16, .92);
		backdrop-filter: blur(14px);
		border-top: 1px solid var(--line);
	}
	.tabbar a { display: grid; justify-items: center; gap: 3px; color: var(--faint); font: 600 9.5px var(--mono); letter-spacing: .12em; text-transform: uppercase; padding: 2px 14px; }
	.tabbar a svg { width: 20px; height: 20px; }
	.tabbar a.on { color: var(--brass); }
}

/* ---- page headers ---- */

.pagehead { display: grid; gap: 8px; }
.pagehead h1 {
	margin: 0;
	font: 400 clamp(30px, 5vw, 44px)/1.04 var(--serif);
	letter-spacing: -.015em;
	text-wrap: balance;
}
.pagehead .under { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; color: var(--dim); font-size: 13.5px; }

.pill {
	display: inline-flex; align-items: center; gap: 6px;
	border: 1px solid var(--line);
	border-radius: 999px;
	padding: 3px 11px;
	font: 600 10.5px var(--mono);
	letter-spacing: .12em; text-transform: uppercase;
	color: var(--dim);
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); }
.pill.ok { color: var(--ok); border-color: rgba(70,200,150,.35); } .pill.ok .dot { background: var(--ok); box-shadow: 0 0 8px rgba(70,200,150,.7); }
.pill.warn { color: var(--warn); border-color: rgba(224,163,61,.4); } .pill.warn .dot { background: var(--warn); }
.pill.crit { color: var(--crit); border-color: rgba(239,128,120,.45); } .pill.crit .dot { background: var(--crit); box-shadow: 0 0 8px rgba(239,128,120,.6); }
.pill.quiet { color: var(--faint); }

/* ---- cards ---- */

.card {
	background: var(--panel);
	border: 1px solid var(--line);
	border-radius: 14px;
	padding: 18px 20px;
	box-shadow: var(--shadow);
	min-width: 0;
}
.card > .kicker { display: block; margin-bottom: 12px; }

/* ---- fleet ---- */

.fleet-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }
@media (max-width: 880px) { .fleet-grid { grid-template-columns: 1fr; } }

.boat-card {
	display: grid; gap: 14px;
	text-align: left;
	background: var(--panel);
	border: 1px solid var(--line);
	border-radius: 16px;
	padding: 20px;
	box-shadow: var(--shadow);
	transition: border-color .18s, transform .18s;
}
.boat-card:hover { border-color: var(--brass-line); transform: translateY(-2px); }
.boat-card .top { display: flex; align-items: baseline; gap: 12px; }
.boat-card h2 { margin: 0; font: 400 25px/1.1 var(--serif); flex: 1; min-width: 0; }
.boat-card .where { color: var(--dim); font-size: 13px; display: flex; gap: 10px; flex-wrap: wrap; }
.boat-card .metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(78px, 1fr)); gap: 10px; border-top: 1px solid var(--line); padding-top: 13px; }
.metric .v { font: 400 22px/1 var(--serif); font-variant-numeric: tabular-nums; }
.metric .v small { font-size: 12px; color: var(--dim); font-family: var(--mono); margin-left: 2px; }
.metric .k { margin-top: 4px; }
.boat-card .alertline { color: var(--crit); font-size: 13px; display: flex; gap: 8px; align-items: center; }
.boat-card .alertline.none { color: var(--faint); }

/* ---- boat page ---- */

.subtabs {
	display: flex; gap: 4px;
	border-bottom: 1px solid var(--line);
	overflow-x: auto; scrollbar-width: none;
}
.subtabs::-webkit-scrollbar { display: none; }
.subtabs button {
	flex: none;
	padding: 10px 16px 12px;
	color: var(--dim);
	font: 600 11px var(--mono); letter-spacing: .16em; text-transform: uppercase;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
}
.subtabs button.on { color: var(--brass); border-bottom-color: var(--brass); }

.stat-strip { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.stat {
	background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
	padding: 15px 17px 12px; box-shadow: var(--shadow);
	display: grid; gap: 2px; min-width: 0;
}
.stat .v { font: 400 32px/1.05 var(--serif); font-variant-numeric: tabular-nums; }
.stat .v small { font: 500 13px var(--mono); color: var(--dim); margin-left: 3px; }
.stat .k { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.stat svg.spark { width: 100%; height: 34px; margin-top: 6px; display: block; }
.spark .line { fill: none; stroke: var(--brass); stroke-width: 1.6; }
.spark .fill { fill: url(#sparkfill); stroke: none; opacity: .5; }
.spark .end { fill: var(--brass-bright); }

.compartments { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); align-items: start; }
@media (max-width: 880px) { .compartments { grid-template-columns: 1fr; } }

.rooms h3, .card h3 { margin: 0 0 4px; font: 400 18px var(--serif); }
.readingrow {
	display: flex; align-items: baseline; gap: 10px;
	padding: 7px 0;
	border-top: 1px solid var(--line);
	font-size: 13.5px;
}
.readingrow:first-of-type { border-top: 0; }
.readingrow .nm { color: var(--dim); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.readingrow .val { font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; }
.readingrow .val .u { color: var(--faint); margin-left: 3px; }
.devhead { display: flex; align-items: center; gap: 8px; margin: 12px 0 2px; }
.devhead:first-child { margin-top: 2px; }
.devhead .microlabel { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.devdot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--faint); }
.devdot.online { background: var(--ok); box-shadow: 0 0 7px rgba(70,200,150,.8); }
.devdot.late { background: var(--warn); }
.devdot.offline, .devdot.silent { background: var(--crit); }
.devdot.off { background: var(--faint); }

/* ---- the vessel stage ---- */

.stage-wrap {
	position: relative;
	border: 1px solid var(--brass-line);
	border-radius: 16px;
	overflow: hidden;
	background:
		radial-gradient(900px 420px at 50% 110%, rgba(201, 149, 72, .07), transparent 65%),
		radial-gradient(700px 300px at 80% -10%, rgba(70, 120, 160, .06), transparent 60%),
		var(--sunken);
	box-shadow: var(--shadow);
}
.stage { height: min(58dvh, 560px); cursor: grab; }
.stage:active { cursor: grabbing; }
.stage canvas { display: block; }
@media (max-width: 880px) { .stage { height: 52dvh; } }

.stage-hint {
	position: absolute; left: 0; right: 0; bottom: 10px;
	text-align: center; pointer-events: none;
	letter-spacing: .14em;
}
.hullpick {
	position: absolute; top: 12px; right: 12px; z-index: 5;
	display: flex; gap: 4px;
	background: rgba(10, 13, 16, .8);
	backdrop-filter: blur(8px);
	border: 1px solid var(--line);
	border-radius: 999px;
	padding: 3px;
}
.hullpick button {
	border-radius: 999px;
	padding: 4px 13px;
	font: 600 10.5px var(--mono);
	letter-spacing: .12em; text-transform: uppercase;
	color: var(--dim);
}
.hullpick button.on { background: rgba(201, 149, 72, .18); color: var(--brass-bright); }

.stage-hint .when-placing { display: none; color: var(--brass-bright); }
.stage-wrap.placing .when-idle { display: none; }
.stage-wrap.placing .when-placing { display: inline; }
.stage-wrap.placing .stage { cursor: crosshair; }
.placebtn { margin-top: 14px; width: 100%; }

.b3d-labels { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.b3d-label {
	position: absolute; top: 0; left: 0;
	pointer-events: auto;
	transform: translate(-200px, -200px);
	translate: -50% -100%;
	background: rgba(10, 13, 16, .82);
	backdrop-filter: blur(6px);
	border: 1px solid var(--brass-line);
	border-radius: 999px;
	padding: 3px 11px;
	font: 600 10px var(--mono);
	letter-spacing: .14em; text-transform: uppercase;
	color: var(--brass-bright);
	white-space: nowrap;
	transition: opacity .15s;
}
.b3d-label.on { background: rgba(201, 149, 72, .22); border-color: var(--brass); color: #fff; }
.b3d-label.crit { color: var(--crit); border-color: rgba(239, 128, 120, .5); }

.drawer {
	position: absolute; z-index: 10;
	top: 12px; right: 12px; bottom: 12px;
	width: min(360px, calc(100% - 24px));
	background: rgba(12, 16, 20, .92);
	backdrop-filter: blur(14px);
	border: 1px solid var(--brass-line);
	border-radius: 14px;
	padding: 16px 18px;
	overflow-y: auto;
	box-shadow: var(--shadow);
	animation: drawerin .22s ease;
}
@keyframes drawerin { from { opacity: 0; transform: translateX(14px); } }
@media (max-width: 880px) {
	.drawer {
		top: auto; left: 8px; right: 8px; bottom: 8px;
		width: auto; max-height: 62%;
		animation-name: drawerup;
	}
	@keyframes drawerup { from { opacity: 0; transform: translateY(16px); } }
}
.drawer-head { display: flex; align-items: flex-start; gap: 10px; }
.drawer-head > div { flex: 1; min-width: 0; }
.drawer-head h3 { font-size: 21px; }
.drawer-close {
	flex: none; width: 30px; height: 30px;
	border: 1px solid var(--line); border-radius: 8px;
	color: var(--dim); font-size: 17px; line-height: 1;
}
.drawer-close:hover { color: var(--ink); border-color: var(--brass-line); }
.drawer .alertcard { margin: 10px 0 4px; }

/* ---- compartment management ---- */

.comprow {
	display: flex; align-items: center; gap: 12px;
	padding: 8px 0;
	border-top: 1px solid var(--line);
}
.comprow:first-child { border-top: 0; }
.comp-input {
	background: transparent;
	border: 1px solid transparent;
	border-radius: 7px;
	color: var(--ink);
	padding: 6px 9px;
	font-size: 14px;
	flex: 1; min-width: 0;
	transition: border-color .15s, background .15s;
}
.comp-input:hover { border-color: var(--line); }
.comp-input:focus { border-color: var(--brass); background: var(--sunken); outline: none; }
.comprow .microlabel { flex: none; }
.comp-remove {
	flex: none;
	border: 1px solid var(--line); border-radius: 7px;
	padding: 5px 11px; font-size: 12px; color: var(--dim);
}
.comp-remove:hover:not(:disabled) { border-color: rgba(239,128,120,.5); color: var(--crit); }
.comp-remove:disabled { opacity: .4; cursor: default; }
.comp-add { display: flex; gap: 10px; margin-top: 12px; }
.comp-add .comp-input { border-color: var(--line); }

.moveline { display: flex; align-items: center; gap: 8px; padding: 2px 0 8px; }
.moveline select {
	background: var(--sunken); border: 1px solid var(--line); border-radius: 7px;
	color: var(--dim); font-size: 12.5px; padding: 4px 8px;
}
.moveline select:focus { border-color: var(--brass); outline: none; color: var(--ink); }

/* ---- switches ---- */

.switchrow { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-top: 1px solid var(--line); }
.switchrow:first-of-type { border-top: 0; }
.switchrow .nm { flex: 1; font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.toggle {
	width: 46px; height: 26px; flex: none;
	border-radius: 999px;
	border: 1px solid var(--line);
	background: var(--sunken);
	position: relative;
	transition: background .18s, border-color .18s;
}
.toggle::after {
	content: '';
	position: absolute; top: 3px; left: 3px;
	width: 18px; height: 18px; border-radius: 50%;
	background: var(--dim);
	transition: transform .18s, background .18s;
}
.toggle.on { background: rgba(201,149,72,.25); border-color: var(--brass); }
.toggle.on::after { transform: translateX(20px); background: var(--brass-bright); }
.toggle.busy { opacity: .5; }
.toggle:disabled { cursor: default; opacity: .45; }
.feedline { color: var(--faint); font-size: 12px; display: flex; align-items: center; gap: 7px; }
.feedline .devdot { width: 6px; height: 6px; }

.modes { display: flex; gap: 6px; flex-wrap: wrap; }
.modes button {
	border: 1px solid var(--line); border-radius: 999px;
	padding: 5px 13px; font-size: 12.5px; color: var(--dim);
}
.modes button.on { border-color: var(--brass); color: var(--brass-bright); background: rgba(201,149,72,.1); }

/* ---- map ---- */

.mapwrap { position: relative; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); }
.mapwrap .map { height: min(66dvh, 620px); background: #0a0e11; }
@media (max-width: 880px) { .mapwrap .map { height: 58dvh; } }
.maptools {
	position: absolute; z-index: 500; top: 10px; left: 10px; right: 10px;
	display: flex; gap: 6px; justify-content: flex-start; pointer-events: none;
}
.maptools button {
	pointer-events: auto;
	background: rgba(10, 13, 16, .88); backdrop-filter: blur(8px);
	border: 1px solid var(--line); border-radius: 999px;
	padding: 5px 13px; font: 600 10.5px var(--mono); letter-spacing: .1em; color: var(--dim);
}
.maptools button.on { color: var(--brass-bright); border-color: var(--brass); }
.mapfoot { padding: 10px 14px; display: flex; gap: 14px; flex-wrap: wrap; color: var(--faint); font-size: 12px; background: var(--panel); border-top: 1px solid var(--line); }
/* Night chart: darken the tiles, keep the vectors bright. */
.map .leaflet-tile-pane { filter: invert(1) hue-rotate(190deg) saturate(.32) brightness(.75) contrast(.9); }
.map .leaflet-container { background: #0a0e11; font: inherit; }

/* ---- alerts ---- */

.alertcard { display: grid; gap: 2px; padding: 13px 16px; border: 1px solid var(--line); border-left: 3px solid var(--warn); border-radius: 10px; background: var(--panel); }
.alertcard.critical { border-left-color: var(--crit); background: linear-gradient(90deg, var(--crit-wash), var(--panel) 40%); }
.alertcard .t { font-weight: 650; font-size: 14.5px; }
.alertcard .d { color: var(--dim); font-size: 13px; }
.alertlist { display: grid; gap: 10px; }
.allclear { display: grid; justify-items: center; gap: 10px; padding: 40px 20px; color: var(--faint); text-align: center; }
.allclear .big { font: 400 22px var(--serif); color: var(--dim); }

/* ---- toasts ---- */

#toasts { position: fixed; z-index: 90; right: 14px; bottom: calc(16px + env(safe-area-inset-bottom)); display: grid; gap: 8px; max-width: min(92vw, 360px); }
@media (max-width: 880px) { #toasts { bottom: calc(78px + env(safe-area-inset-bottom)); } }
.toast {
	background: var(--raised); border: 1px solid var(--line); border-radius: 10px;
	padding: 11px 14px; font-size: 13.5px; box-shadow: var(--shadow);
	animation: toastin .22s ease;
}
.toast.ok { border-color: rgba(70,200,150,.4); }
.toast.err { border-color: rgba(239,128,120,.5); }
@keyframes toastin { from { opacity: 0; transform: translateY(8px); } }

.skeleton { border-radius: 10px; background: linear-gradient(100deg, var(--panel) 40%, var(--raised) 50%, var(--panel) 60%) 0 0/300% 100%; animation: shimmer 1.4s infinite linear; min-height: 90px; }
@keyframes shimmer { to { background-position: -300% 0; } }

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { animation: none !important; transition: none !important; }
}

.errorbox { text-align: center; padding: 46px 18px; color: var(--dim); display: grid; gap: 12px; justify-items: center; }
.errorbox .big { font: 400 24px var(--serif); color: var(--ink); }

/* ---- the console: the reference dashboard, worn by real data ---- */

.c2 {
	border: 1px solid var(--brass-line);
	border-radius: 18px;
	overflow: hidden;
	background:
		radial-gradient(110% 80% at 50% -5%, #131a22 0%, #0b1016 45%, #07090c 100%);
	box-shadow: var(--shadow);
}

.c2-head {
	display: flex;
	justify-content: space-between;
	gap: 14px;
	align-items: flex-start;
	padding: 18px clamp(16px, 3vw, 28px) 14px;
	border-bottom: 1px solid var(--line);
}
.c2-head-left { display: grid; gap: 5px; }
.c2-sub { font-size: 13px; color: var(--dim); }
.c2-session { display: grid; gap: 2px; justify-items: end; text-align: right; }
.c2-session-badge {
	font: 600 10px var(--mono);
	letter-spacing: .16em;
	color: var(--ok);
	border: 1px solid rgba(70, 200, 150, .35);
	border-radius: 999px;
	padding: 3px 10px;
}
.c2-session-line { font-size: 12px; color: var(--dim); }
.c2-session-line.dim { color: var(--faint); font-variant-numeric: tabular-nums; }

.c2-body {
	display: grid;
	grid-template-columns: 168px 1fr minmax(240px, 300px);
	gap: 0;
	min-height: 420px;
}
@media (max-width: 1020px) { .c2-body { grid-template-columns: 148px 1fr; } .c2-controls { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--line); flex-direction: row; flex-wrap: wrap; } }
@media (max-width: 700px) { .c2-body { grid-template-columns: 1fr; } .c2-rail { flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); padding: 8px; } .c2-rail-gap { display: none; } .c2-status { display: none; } }

.c2-rail {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 18px 12px;
	border-right: 1px solid var(--line);
}
.c2-rail-item {
	display: flex;
	align-items: center;
	gap: 11px;
	padding: 11px 12px;
	border-radius: 10px;
	color: var(--dim);
	font-size: 13.5px;
	border: 1px solid transparent;
}
.c2-rail-item:hover { color: var(--ink); }
.c2-rail-item.on {
	color: var(--brass-bright);
	border-color: var(--brass-line);
	background: rgba(201, 149, 72, .08);
}
.c2-rail-icon { position: relative; display: block; flex: none; }
.c2-rail-icon svg { width: 19px; height: 19px; display: block; }
.c2-lamp {
	position: absolute; top: -3px; right: -7px;
	width: 7px; height: 7px; border-radius: 50%;
	background: var(--warn);
	box-shadow: 0 0 8px currentColor;
}
.c2-lamp.crit { background: var(--crit); animation: c2pulse 1.8s ease-in-out infinite; }
@keyframes c2pulse { 50% { opacity: .35; } }
.c2-rail-gap { flex: 1; }

.c2-status { display: grid; gap: 9px; padding: 0 4px 4px; }
.c2-status-row { display: grid; gap: 1px; }
.c2-status-label {
	font: 600 9px var(--mono);
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--faint);
}
.c2-status-value { font-size: 12.5px; color: var(--dim); font-variant-numeric: tabular-nums; }
.c2-status-value.good { color: var(--ok); }

.c2-hero {
	position: relative;
	padding: 22px clamp(14px, 3vw, 30px) 8px;
	display: flex;
	flex-direction: column;
	min-width: 0;
}
.c2-boatname {
	margin: 0;
	font: 400 clamp(26px, 3.4vw, 36px)/1.05 var(--serif);
	letter-spacing: .04em;
	color: var(--brass-bright);
	text-transform: uppercase;
}
.c2-dims { margin-top: 5px; font-size: 13px; color: var(--dim); }

.c2-water {
	position: relative;
	flex: 1;
	display: grid;
	align-content: center;
	justify-items: center;
	min-height: 240px;
	margin-top: 6px;
	background:
		radial-gradient(70% 45% at 50% 78%, rgba(201, 149, 72, .10), transparent 70%),
		radial-gradient(90% 60% at 50% 90%, rgba(30, 48, 63, .5), transparent 75%);
}
.c2-boat {
	width: min(96%, 640px);
	height: auto;
	user-select: none;
	-webkit-user-drag: none;
	filter: drop-shadow(0 14px 22px rgba(0, 0, 0, .5));
}
.c2-mirror {
	position: absolute;
	top: calc(50% + 24%);
	transform: scaleY(-1);
	opacity: .18;
	filter: blur(2px);
	-webkit-mask-image: linear-gradient(to top, rgba(0,0,0,.8), transparent 55%);
	mask-image: linear-gradient(to top, rgba(0,0,0,.8), transparent 55%);
	pointer-events: none;
}

.c2-controls {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 20px 16px;
	border-left: 1px solid var(--line);
	overflow-y: auto;
}
.c2-control {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 14px 16px;
	border: 1px solid var(--line);
	border-radius: 13px;
	background: rgba(255, 255, 255, .015);
	min-width: 200px;
}
.c2-control.on { border-color: var(--brass-line); }
.c2-control-text { flex: 1; display: grid; gap: 2px; min-width: 0; }
.c2-control-name { font-size: 14.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.c2-control-state {
	font: 600 10px var(--mono);
	letter-spacing: .14em;
	color: var(--faint);
}
.c2-control.on .c2-control-state { color: var(--brass-bright); }
.c2-controls-empty { align-self: center; margin: auto; }

.c2-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
	gap: 1px;
	background: var(--line);
	border-top: 1px solid var(--line);
}
.c2-tile {
	display: grid;
	gap: 3px;
	padding: 14px 16px 12px;
	background: #0c1116;
	min-width: 0;
}
.c2-tile.crit .c2-tile-value { color: var(--crit); }
.c2-tile-label {
	font: 600 9.5px var(--mono);
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--faint);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.c2-tile-value {
	font: 400 26px/1.05 var(--serif);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}
.c2-tile-unit { font: 500 12px var(--mono); color: var(--dim); margin-left: 3px; }
.c2-tile-sub { font-size: 11.5px; color: var(--faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.c2-tile-none { padding: 16px; background: #0c1116; }

.c2-edit-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
#c2editor { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); margin-top: 12px; }
.c2-edit-group { display: grid; gap: 2px; align-content: start; }
.c2-edit-row {
	display: flex; align-items: center; gap: 9px;
	padding: 6px 8px; border-radius: 8px; cursor: pointer; font-size: 13.5px;
}
.c2-edit-row:hover { background: var(--raised); }
.c2-edit-row input { accent-color: var(--brass); }
.c2-edit-row span:first-of-type { flex: 1; }
.c2-edit-now { font: 500 12px var(--mono); color: var(--faint); }

/* ---- console, likeness pass: photo hero, weather, richer controls, tile cards ---- */

.c2-hero-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.c2-wx { display: flex; gap: 16px; padding-top: 6px; white-space: nowrap; }
.c2-wx-item { font-size: 13px; color: var(--dim); }

.c2-photo {
	position: absolute; inset: 0;
	border-radius: 14px;
	background-size: cover;
	background-position: center 62%;
	box-shadow: inset 0 0 80px 30px rgba(5, 7, 10, .85), inset 0 0 24px 8px rgba(5, 7, 10, .5);
}
.c2-photo.render {
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
	box-shadow: none;
}
.c2-water {
	position: relative;
	flex: 1;
	min-height: 280px;
	margin-top: 10px;
}
.c2-view {
	position: absolute;
	left: 50%; bottom: 10px;
	transform: translateX(-50%);
	display: grid; justify-items: center; gap: 5px;
	z-index: 2;
}
.c2-view-dots { display: flex; gap: 7px; }
.c2-view-dots button {
	width: 8px; height: 8px;
	border-radius: 50%;
	background: var(--faint);
	opacity: .5;
}
.c2-view-dots button.on { background: var(--brass-bright); opacity: 1; }

.c2-control { display: grid; gap: 0; padding: 13px 15px; }
.c2-control-row { display: flex; align-items: center; gap: 12px; }
.c2-cicon {
	flex: none;
	width: 34px; height: 34px;
	display: grid; place-items: center;
	border: 1px solid var(--brass-line);
	border-radius: 10px;
	color: var(--brass-bright);
}
.c2-cicon svg { width: 18px; height: 18px; }
.c2-slider-row { display: flex; align-items: center; gap: 10px; padding: 10px 2px 2px 46px; }
.c2-slider-ic { color: var(--faint); font-size: 13px; }
.c2-slider {
	flex: 1;
	appearance: none;
	height: 3px;
	border-radius: 2px;
	background: linear-gradient(90deg, var(--brass) 60%, var(--line) 60%);
	outline-offset: 4px;
}
.c2-slider::-webkit-slider-thumb {
	appearance: none;
	width: 14px; height: 14px;
	border-radius: 50%;
	background: var(--brass-bright);
	border: 0;
}
.c2-control-sub { padding: 8px 2px 0 46px; font-size: 12px; color: var(--dim); }
.c2-showall {
	display: flex; align-items: center; justify-content: center; gap: 6px;
	padding: 12px;
	border: 1px solid var(--line);
	border-radius: 12px;
	color: var(--dim);
	font: 600 11px var(--mono);
	letter-spacing: .12em;
	text-transform: uppercase;
}
.c2-showall:hover { color: var(--brass-bright); border-color: var(--brass-line); }

/* tiles become separate cards with an icon in the corner */
.c2-tiles {
	grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
	gap: 10px;
	padding: 14px clamp(14px, 2.5vw, 24px) 18px;
	background: transparent;
}
.c2-tile {
	position: relative;
	border: 1px solid var(--line);
	border-radius: 13px;
	padding: 13px 15px 11px;
}
.c2-tile-ic {
	position: absolute;
	top: 11px; right: 11px;
	color: var(--faint);
}
.c2-tile-ic svg { width: 16px; height: 16px; display: block; }
.c2-tile .c2-tile-label { padding-right: 22px; }

/* Dashboard 2 is a control panel, not an article: it wants width more than it
   wants margins. On this tab the pane breaks out of the reading measure and the
   page padding, because the panel inside decides its own layout from the width
   it is given - and starved of width it falls back to the single-column phone
   layout, on a tablet held sideways, which is where it is most likely to be
   used. Full screen goes further; this is what it looks like before you ask. */
.main:has(.dash2-wrap) { padding-left: 0; padding-right: 0; padding-top: 14px; }
.main:has(.dash2-wrap) .main-inner { max-width: none; }
@media (min-width: 900px) {
	.main:has(.dash2-wrap) .pagehead,
	.main:has(.dash2-wrap) .subtabs { padding-inline: clamp(16px, 4vw, 44px); }
}

/* On a short screen the page's own head is the first thing to go: the panel
   already says which boat this is, in larger type, forty pixels lower - and
   those forty pixels are the difference between reading the strip along the
   bottom and scrolling to it. The tabs stay; they are how you leave. */
@media (min-width: 900px) and (max-height: 950px) {
	.main:has(.dash2-wrap) .pagehead { display: none; }
	.main:has(.dash2-wrap) { padding-top: 8px; }
	.main:has(.dash2-wrap) .main-inner { gap: 10px; }
}

/* ---- dashboard 2: the boatlink.fi remote-control panel, in its own frame.
   The frame is told its height by the panel inside it, so the page scrolls
   once rather than twice; full screen hands the whole viewport over. */
.dash2-wrap{position:relative;background:#050607;border-radius:16px;height:1100px;overflow:hidden;transition:height .2s ease}
.dash2-frame{display:block;width:100%;height:100%;border:0;border-radius:16px;background:#050607}
.dash2-full{position:absolute;top:14px;right:18px;z-index:2;padding:8px 14px;border-radius:999px;
	border:1px solid rgba(255,255,255,.14);background:rgba(8,11,16,.78);color:#c8cdd4;
	font:700 10px ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;cursor:pointer;
	backdrop-filter:blur(6px);transition:.2s ease}
.dash2-full:hover{color:#f0d49b;border-color:rgba(201,149,72,.45)}
/* In full screen the button has said its piece: it fades a few seconds
   in, and comes back on a touch - it is still the way out. */
.dash2-wrap:fullscreen .dash2-full,.dash2-wrap:-webkit-full-screen .dash2-full{transition:opacity .6s ease}
.dash2-wrap:fullscreen .dash2-full[data-idle="1"],.dash2-wrap:-webkit-full-screen .dash2-full[data-idle="1"]{opacity:0;pointer-events:none}
.dash2-wrap:fullscreen,.dash2-wrap:-webkit-full-screen{border-radius:0;overflow:hidden}
/* !important is the one thing that outranks the inline height the panel
   asks for - without it the frame keeps its content height inside a
   screen-sized box, which is the spill past the glass. */
.dash2-wrap:fullscreen .dash2-frame,.dash2-wrap:-webkit-full-screen .dash2-frame{height:100%!important;width:100%!important;border-radius:0;transform:none!important}
@media(max-width:760px){.dash2-frame{border-radius:12px}.dash2-full{top:10px;right:10px;padding:7px 11px}}

/* ---- dashboard 2's wardrobe: the make-it-yours card below the frame.
   Deliberately outside .dash2-wrap - full screen shows the frame alone, so a
   mounted tablet cannot be edited by a stray elbow. */
.dash2-custom { display: grid; gap: 14px; margin: 0 clamp(16px, 4vw, 44px); }
.d2c-lead { margin: -4px 0 0; color: var(--dim); font-size: 13.5px; max-width: 72ch; }

.d2c-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 18px;
}
.d2c-block { display: grid; gap: 8px; align-content: start; }
.d2c-block h4 {
	margin: 0 0 2px;
	font: 600 13px/1.3 var(--sans);
	color: var(--ink);
}
.d2c-block h4 small { display: block; font-weight: 500; font-size: 11.5px; color: var(--faint); }

.d2c-row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 10px;
	padding: 8px 10px;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--sunken);
	cursor: pointer;
}
.d2c-row:has(input:checked) { border-color: var(--brass-line); background: var(--raised); }
.d2c-row input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--brass); }
.d2c-name { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.d2c-name small { display: block; color: var(--faint); font-size: 11px; }
.d2c-row select {
	background: var(--panel);
	color: var(--ink);
	border: 1px solid var(--line);
	border-radius: 8px;
	font-size: 12px;
	padding: 5px 7px;
	max-width: 150px;
}
.d2c-none { margin: 0; color: var(--faint); font-size: 13px; }

.d2c-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.d2c-tile {
	display: flex; align-items: center; gap: 8px;
	padding: 7px 10px;
	border: 1px solid var(--line);
	border-radius: 9px;
	background: var(--sunken);
	font-size: 12.5px;
	cursor: pointer;
}
.d2c-tile:has(input:checked) { border-color: var(--brass-line); background: var(--raised); }
.d2c-tile input { width: 14px; height: 14px; accent-color: var(--brass); }

.d2c-vessels { display: grid; gap: 6px; }
.d2c-vessel {
	display: flex; align-items: center; gap: 9px;
	padding: 9px 11px;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--sunken);
	font-size: 13px;
	cursor: pointer;
}
.d2c-vessel:has(input:checked) { border-color: var(--brass-line); background: var(--raised); }
.d2c-vessel input { accent-color: var(--brass); }

.d2c-foot { display: flex; align-items: center; gap: 14px; }
.d2c-foot .btn-brass { padding: 10px 18px; }
.d2c-status { color: var(--ok); letter-spacing: .08em; }

@media (max-width: 900px) {
	.dash2-custom { margin-inline: 0; }
}

/* The rename field inside a switch row, and the per-tile source dropdown. */
.d2c-rename {
	width: 100%;
	background: var(--panel);
	border: 1px solid var(--line);
	border-radius: 7px;
	color: var(--ink);
	font-size: 13px;
	padding: 5px 8px;
}
.d2c-rename:focus { border-color: var(--brass); outline: none; }
.d2c-tile.has-source { flex-wrap: wrap; }
.d2c-tile select {
	flex-basis: 100%;
	background: var(--panel);
	color: var(--dim);
	border: 1px solid var(--line);
	border-radius: 7px;
	font-size: 11.5px;
	padding: 4px 6px;
	margin-top: 2px;
}

/* Slot cards: one per dashboard position, position number on the left. */
.d2c-slot {
	display: grid;
	grid-template-columns: 52px minmax(0, 1fr);
	align-items: start;
	gap: 6px 10px;
	padding: 8px 10px;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--sunken);
	margin-bottom: 6px;
}
.d2c-slot:has(select:first-of-type option:checked[value=""]):not(:hover) { opacity: .66; }
.d2c-slot-n {
	font: 600 9.5px/2.6 var(--mono);
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--faint);
	white-space: nowrap;
}
.d2c-slot select, .d2c-slot .d2c-rename {
	width: 100%;
	background: var(--panel);
	color: var(--ink);
	border: 1px solid var(--line);
	border-radius: 8px;
	font-size: 12.5px;
	padding: 6px 8px;
}
.d2c-slot-more {
	grid-column: 2;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 6px;
}
.d2c-slot-more select { max-width: 165px; }
.d2c-slot-more:has(> select:only-child) { grid-template-columns: 1fr; }
.d2c-slot-more > select:only-child { max-width: none; color: var(--dim); }

/* The strip gallery: the cards as the strip will draw them, shown first. */
.d2c-wide { grid-column: 1 / -1; }
.d2c-cardgroup { display: grid; gap: 8px; margin-bottom: 14px; }
.d2c-grouplabel {
	font: 600 9.5px/1 var(--mono);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--faint);
}
.d2c-cardgrid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: 8px;
}
.d2c-card {
	display: grid;
	gap: 3px;
	text-align: left;
	padding: 10px 12px;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--sunken);
	cursor: pointer;
	transition: border-color .15s ease, opacity .15s ease;
}
.d2c-card small {
	font: 600 9px/1.2 var(--mono);
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--faint);
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.d2c-card strong {
	font: 400 20px/1.1 var(--serif);
	color: var(--ink);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.d2c-card span {
	font-size: 10.5px;
	color: var(--dim);
	min-height: 13px;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.d2c-card.on { border-color: var(--brass-line); background: var(--raised); }
.d2c-card.on small { color: var(--brass); }
/* The gallery wears the same truth as the strip: amber for a stale
   source, red for one expected and long unheard. */
.d2c-card.stale-a strong { color: #f59e0b; }
.d2c-card.stale-r strong { color: #ef4444; }
.d2c-card:not(.on) { opacity: .62; }
.d2c-card:not(.on):hover { opacity: 1; border-color: var(--brass-line); }

/* The systems picker: which cells this boat carries. */
.d2c-syslist { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.d2c-sys {
	display: flex; align-items: center; gap: 8px;
	padding: 7px 10px;
	border: 1px solid var(--line);
	border-radius: 9px;
	background: var(--sunken);
	font-size: 12.5px;
	cursor: pointer;
}
.d2c-sys:has(input:checked) { border-color: var(--brass-line); background: var(--raised); }
.d2c-sys input { accent-color: var(--brass); }
