mega-plant/app/globals.css

155 lines
7.6 KiB
CSS
Raw Normal View History

@import "tailwindcss";
/* Leaflet + marker-cluster must be global stylesheets. Importing them inside
components/PlantMap.tsx works for leaflet.css but the cluster stylesheet gets
dropped, because that component is behind a `next/dynamic` ssr:false boundary
whose CSS is not linked in the initial HTML. Without these, cluster bubbles
land unpositioned and unstyled. */
@import "leaflet/dist/leaflet.css";
@import "leaflet.markercluster/dist/MarkerCluster.css";
/* Enable dark mode via .dark class on html */
@custom-variant dark (&:where(.dark, .dark *));
/* Coolors palette — stays the same in both modes */
@theme {
--color-sunny: #EDAE49;
--color-brick: #D1495B;
--color-seaweed: #00798C;
--color-casual: #30638E;
--color-indigo: #003D5B;
/* Part A.4: chart hues — deeper steps of the same brand hues, validated for CVD/contrast.
Brand palette (#EDAE49/#00798C/#D1495B) does NOT change; these are read only by chart marks. */
--color-chart-income: #0090A6;
--color-chart-fixed: #BE851F;
Charts: a profit line that changes colour, and a Series toggle Profit was a single always-teal line, so a month that lost money looked like a month that made a little. It is now drawn per sign: one <Line> per same-sign run, plus a gradient <Line> across each crossing. Recharts draws a Line as one <Curve> path, so <Cell> cannot recolour a segment — separate series are the only way. Every variant is a key on the ONE shared dataset rather than a sliced `data` prop, because Recharts builds a categorical axis by concatenating every series' data and a short slice re-adds the month labels ("Jan … Aug, Jan … Aug"). The tooltip needs a custom `content` component to fold those per-run keys back into a single profit row. Two honesty rules: profit stays null in a month with no income figure (treating it as 0 drew a green dot for a month that was never billed), and a month with no running-cost row gets a hollow dot, because its profit is optimistic. The toolbar's Series button toggles which lines a card draws, remembered in localStorage. A hidden series takes its legend entry and its Y axis with it, so there is never an axis for a line that is not drawn, and the last visible series cannot be switched off. Palette: Running moves off red to the project's existing brand purple, because red is now reserved for a loss and a red Running line next to a red loss segment was unreadable. `--color-chart-loss` and `--color-chart-profit` are separate tokens on purpose — loss used to read the Running token, so recolouring Running silently dragged the red with it. /charts alone now reads profit including running cost, so the card badge, the profit line and the Profit bars view cannot disagree. Scoped to the page: lib/profit.ts keeps its workbook default for every other surface.
2026-10-03 07:20:16 +00:00
--color-chart-running: #8B5CF6;
/* A month that did not make profit. Its own token so moving the Running line
cannot drag the profit-loss red along with it. */
--color-chart-loss: #C13B4D;
/* Profit-positive. The client's chosen bright green, 2026-10-02 — deliberately
outside the Coolors brand set so the profit line reads as its own series and
not as another teal. */
--color-chart-profit: #7A9E06;
--color-brand-blue: #30638E;
--color-brand-orange: #EDAE49;
--color-brand-red: #D1495B;
--color-brand-green: #00798C;
--color-brand-purple: #8B5CF6;
--color-brand-cyan: #00798C;
--color-brand-pink: #D1495B;
--color-brand-yellow: #EDAE49;
/* Light theme (default) */
--color-bg: #f5f7fb;
--color-surface: #ffffff;
--color-surface-muted: #f9fafb;
--color-border: #e5e7eb;
--color-border-soft: #f3f4f6;
--color-text: #003D5B;
--color-text-muted: #6b7280;
--color-text-soft: #9ca3af;
--color-row-hover: rgba(0, 0, 0, 0.02);
/* "Ink" steps — the light-mode colour for text that borrows a brand hue.
The base brand palette above is never used as text on a light surface unless
it clears 4.5:1; these names exist so `text-accent-ink` works in BOTH modes
and only its value changes. See the .dark block for the dark counterparts. */
--color-accent-ink: #30638E;
--color-brick-ink: #D1495B;
--color-indigo-ink: #003D5B;
}
/* Dark theme overrides */
.dark {
--color-bg: #0f151b;
--color-surface: #1e2732;
--color-surface-muted: #182029;
--color-border: #303c48;
--color-border-soft: #26313c;
--color-text: #e8eef4;
--color-text-muted: #adb8c2;
--color-text-soft: #87919a;
--color-row-hover: rgba(255, 255, 255, 0.04);
/* Dark "ink" steps. The base brand hues are correct as *fills* but fail WCAG AA
as text on a dark surface (seaweed 3.6:1, casual 2.9:1, brick 3.7:1, indigo 1.6:1).
These are lighter steps of the same hues, reaching 4.8–7.3:1. Text-only —
never a fill — so the @theme brand palette stays untouched. */
--color-accent-ink: #2BB0C4;
--color-brick-ink: #E86E7E;
--color-indigo-ink: #7FA8C9;
/* Part A.4: dark-mode chart hues */
--color-chart-income: #00A6BE;
--color-chart-fixed: #BE851F;
Charts: a profit line that changes colour, and a Series toggle Profit was a single always-teal line, so a month that lost money looked like a month that made a little. It is now drawn per sign: one <Line> per same-sign run, plus a gradient <Line> across each crossing. Recharts draws a Line as one <Curve> path, so <Cell> cannot recolour a segment — separate series are the only way. Every variant is a key on the ONE shared dataset rather than a sliced `data` prop, because Recharts builds a categorical axis by concatenating every series' data and a short slice re-adds the month labels ("Jan … Aug, Jan … Aug"). The tooltip needs a custom `content` component to fold those per-run keys back into a single profit row. Two honesty rules: profit stays null in a month with no income figure (treating it as 0 drew a green dot for a month that was never billed), and a month with no running-cost row gets a hollow dot, because its profit is optimistic. The toolbar's Series button toggles which lines a card draws, remembered in localStorage. A hidden series takes its legend entry and its Y axis with it, so there is never an axis for a line that is not drawn, and the last visible series cannot be switched off. Palette: Running moves off red to the project's existing brand purple, because red is now reserved for a loss and a red Running line next to a red loss segment was unreadable. `--color-chart-loss` and `--color-chart-profit` are separate tokens on purpose — loss used to read the Running token, so recolouring Running silently dragged the red with it. /charts alone now reads profit including running cost, so the card badge, the profit line and the Profit bars view cannot disagree. Scoped to the page: lib/profit.ts keeps its workbook default for every other surface.
2026-10-03 07:20:16 +00:00
--color-chart-running: #8B5CF6;
--color-chart-loss: #D94F60;
--color-chart-profit: #7A9E06;
}
html, body {
background: var(--color-bg);
color: var(--color-text);
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
* { -webkit-font-smoothing: antialiased; }
/* Smooth color transition when toggling themes */
body, .dark body { transition: background-color 0.2s ease, color 0.2s ease; }
.recharts-cartesian-axis-tick text { fill: var(--color-text-soft); font-size: 11px; }
Charts: a profit line that changes colour, and a Series toggle Profit was a single always-teal line, so a month that lost money looked like a month that made a little. It is now drawn per sign: one <Line> per same-sign run, plus a gradient <Line> across each crossing. Recharts draws a Line as one <Curve> path, so <Cell> cannot recolour a segment — separate series are the only way. Every variant is a key on the ONE shared dataset rather than a sliced `data` prop, because Recharts builds a categorical axis by concatenating every series' data and a short slice re-adds the month labels ("Jan … Aug, Jan … Aug"). The tooltip needs a custom `content` component to fold those per-run keys back into a single profit row. Two honesty rules: profit stays null in a month with no income figure (treating it as 0 drew a green dot for a month that was never billed), and a month with no running-cost row gets a hollow dot, because its profit is optimistic. The toolbar's Series button toggles which lines a card draws, remembered in localStorage. A hidden series takes its legend entry and its Y axis with it, so there is never an axis for a line that is not drawn, and the last visible series cannot be switched off. Palette: Running moves off red to the project's existing brand purple, because red is now reserved for a loss and a red Running line next to a red loss segment was unreadable. `--color-chart-loss` and `--color-chart-profit` are separate tokens on purpose — loss used to read the Running token, so recolouring Running silently dragged the red with it. /charts alone now reads profit including running cost, so the card badge, the profit line and the Profit bars view cannot disagree. Scoped to the page: lib/profit.ts keeps its workbook default for every other surface.
2026-10-03 07:20:16 +00:00
/* Round 4: no text under 12px on mobile. This CSS rule beats Recharts' tick
fontSize prop, so the bump has to happen here or nowhere. */
@media (max-width: 1023px) {
Charts: a profit line that changes colour, and a Series toggle Profit was a single always-teal line, so a month that lost money looked like a month that made a little. It is now drawn per sign: one <Line> per same-sign run, plus a gradient <Line> across each crossing. Recharts draws a Line as one <Curve> path, so <Cell> cannot recolour a segment — separate series are the only way. Every variant is a key on the ONE shared dataset rather than a sliced `data` prop, because Recharts builds a categorical axis by concatenating every series' data and a short slice re-adds the month labels ("Jan … Aug, Jan … Aug"). The tooltip needs a custom `content` component to fold those per-run keys back into a single profit row. Two honesty rules: profit stays null in a month with no income figure (treating it as 0 drew a green dot for a month that was never billed), and a month with no running-cost row gets a hollow dot, because its profit is optimistic. The toolbar's Series button toggles which lines a card draws, remembered in localStorage. A hidden series takes its legend entry and its Y axis with it, so there is never an axis for a line that is not drawn, and the last visible series cannot be switched off. Palette: Running moves off red to the project's existing brand purple, because red is now reserved for a loss and a red Running line next to a red loss segment was unreadable. `--color-chart-loss` and `--color-chart-profit` are separate tokens on purpose — loss used to read the Running token, so recolouring Running silently dragged the red with it. /charts alone now reads profit including running cost, so the card badge, the profit line and the Profit bars view cannot disagree. Scoped to the page: lib/profit.ts keeps its workbook default for every other surface.
2026-10-03 07:20:16 +00:00
.recharts-cartesian-axis-tick text { font-size: 12px; }
.text-\[10px\], .text-\[11px\] { font-size: 12px; }
.leaflet-control-zoom a { width: 44px !important; height: 44px !important; line-height: 44px !important; }
.leaflet-control-attribution { font-size: 12px !important; }
.leaflet-control-attribution a, .leaflet-popup-content a {
display: inline-flex; align-items: center; min-width: 44px; min-height: 44px;
}
.leaflet-popup-close-button { width: 44px !important; height: 44px !important; }
Charts: a profit line that changes colour, and a Series toggle Profit was a single always-teal line, so a month that lost money looked like a month that made a little. It is now drawn per sign: one <Line> per same-sign run, plus a gradient <Line> across each crossing. Recharts draws a Line as one <Curve> path, so <Cell> cannot recolour a segment — separate series are the only way. Every variant is a key on the ONE shared dataset rather than a sliced `data` prop, because Recharts builds a categorical axis by concatenating every series' data and a short slice re-adds the month labels ("Jan … Aug, Jan … Aug"). The tooltip needs a custom `content` component to fold those per-run keys back into a single profit row. Two honesty rules: profit stays null in a month with no income figure (treating it as 0 drew a green dot for a month that was never billed), and a month with no running-cost row gets a hollow dot, because its profit is optimistic. The toolbar's Series button toggles which lines a card draws, remembered in localStorage. A hidden series takes its legend entry and its Y axis with it, so there is never an axis for a line that is not drawn, and the last visible series cannot be switched off. Palette: Running moves off red to the project's existing brand purple, because red is now reserved for a loss and a red Running line next to a red loss segment was unreadable. `--color-chart-loss` and `--color-chart-profit` are separate tokens on purpose — loss used to read the Running token, so recolouring Running silently dragged the red with it. /charts alone now reads profit including running cost, so the card badge, the profit line and the Profit bars view cannot disagree. Scoped to the page: lib/profit.ts keeps its workbook default for every other surface.
2026-10-03 07:20:16 +00:00
}
.recharts-cartesian-grid line { stroke: var(--color-border-soft); }
.recharts-default-tooltip {
background: rgba(255,255,255,0.98) !important;
border: 1px solid #e5e7eb !important;
border-radius: 12px !important;
box-shadow: 0 4px 20px rgba(0,0,0,0.08) !important;
font-size: 12px !important;
padding: 8px 12px !important;
}
.recharts-tooltip-label { color: #003D5B !important; font-weight: 600 !important; margin-bottom: 4px !important; }
.recharts-legend-item-text { color: #6b7280 !important; font-size: 12px !important; }
.dark .recharts-default-tooltip {
background: rgba(30, 39, 50, 0.98) !important;
border: 1px solid #303c48 !important;
color: #e8eef4 !important;
}
.dark .recharts-tooltip-label { color: #e8eef4 !important; }
.dark .recharts-legend-item-text { color: #adb8c2 !important; }
/* Employee clock: generous touch targets, existing Plant palette. */
.plant-clock-page { color: var(--color-text); font-size: 14px; }
.plant-clock-panel { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 16px; }
.plant-clock-eyebrow { font-size: 12px; letter-spacing: .12em; font-weight: 600; color: var(--color-text-muted); }
.plant-clock-button { display: inline-flex; justify-content: center; align-items: center; gap: 8px; min-height: 44px; min-width: 44px; padding: 10px 16px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; text-align: center; }
.plant-clock-button:disabled { opacity: .5; cursor: not-allowed; }
.plant-clock-button:focus-visible, .plant-clock-input:focus-visible { outline: 2px solid var(--color-accent-ink); outline-offset: 3px; }
.plant-clock-primary { background: #30638E; color: white; }
.plant-clock-primary:hover:not(:disabled) { background: #003D5B; }
.plant-clock-secondary { border: 1px solid var(--color-border); background: var(--color-surface); color: var(--color-text); }
.plant-clock-secondary:hover:not(:disabled) { background: var(--color-bg); }
.plant-clock-input { display: block; width: 100%; min-width: 0; min-height: 48px; border: 1px solid var(--color-border); border-radius: 10px; padding: 10px 12px; font-size: 16px; background: var(--color-surface); color: var(--color-text); }
.plant-clock-warning { padding: 12px 14px; border-radius: 10px; border: 1px solid #EDAE4980; background: #EDAE4915; font-size: 14px; line-height: 1.6; overflow-wrap: anywhere; }
.plant-camera { position: relative; overflow: hidden; display: grid; place-items: center; border-radius: 12px; min-height: min(62svh, 520px); background: #003D5B; color: white; }
.plant-clock-banner { display: flex; align-items: center; gap: 12px; padding: 14px 16px; border-radius: 12px; box-shadow: 0 8px 24px rgb(0 0 0 / .25); }
.plant-camera-compact { min-height: min(34svh, 300px); }
.plant-scan-frame { display: grid; place-items: center; width: 154px; height: 140px; border: 2px solid #EDAE49; border-radius: 16px; color: #EDAE49; }
.plant-clock-status { display: inline-flex; align-items: center; border-radius: 7px; background: var(--color-bg); color: var(--color-text-muted); padding: 5px 9px; font-size: 12px; font-weight: 600; white-space: nowrap; }
.plant-clock-status-in { background: #00798C15; color: var(--color-accent-ink); }