/* Otematata CSS — nextgen (Bootstrap 5)  [v3.0.0]
 *
 * Goal: seed the v3.x data-feed series from the promoted v2.0.0 original page.
 * Derived from otematata.modern.css with two kinds of
 * addition:
 *   1. Base parity fixes so BS5's reboot/grid don't shift the fixed-width
 *      layout (body font-size, .container max-width).
 *   2. A "Bootstrap 5 component" block that styles the native BS5 components
 *      (.card, .badge) and the few BS3 helpers BS5 dropped (col-xs grid,
 *      pull-left/right) so they look exactly like the old BS3 panels/pills.
 *
 * Light only. Everything above the "Phone" section is the fixed 1000px layout
 * (desktop and tablet) and is the unconditional base; the Phone section at the
 * bottom is scoped to html.phone (set by the page for phones only) and never
 * applies elsewhere, so the desktop render is unchanged.
 *
 * otematata.modern.css remains the stylesheet for the v2.x page; this one is
 * loaded only by otematata_nextgen.php.
 */

html, body {
	margin:0;
	padding:0;
	background: #E6E6E6;
	color:#000;
	font-size: 14px;          /* BS3 body default; BS5 base is 16px — pin for parity */
	line-height: 1.25;
	font-family: Arial, Helvetica, sans-serif;
}

body {
	margin:0;
	padding:0;
	background: #E6E6E6 url(/images/borders.gif) repeat-y center;
	word-wrap:break-word;
}

.page {
	max-width: 1000px;
	min-width: 960px;
	margin:0 auto;
	position: relative;
	overflow: hidden;
	background: #FFF;
}

/* The page is fixed-width by design. BS5's .container carries responsive
 * max-width breakpoints; neutralise them so the content fills .page instead of
 * snapping between breakpoints (which looked "responsive"). */
.container {
	width: auto;
	max-width: none;
    margin-left: 10px;
	margin-right: 10px;
	padding-left: 0;
	padding-right: 0;
}

a {
	color: #006699;
}

.leading200 { line-height: 200%; }
.leading180 { line-height: 180%; }
.leading150 { line-height: 150%; }
.leading100 { line-height: 100%; }

.header {
	color: white;
    /* background: steelblue; */
    background-color: #428bca;
	width: 100%;
	max-width: 1000px;
	/* Nextgen gives the full-width valley enough room to retain more sky. */
	height: 235px;
}

.footer {
	color: white;
	/* background: steelblue; */
  	background-color: #428bca;
	width: 100%;
	max-width: 1000px;
	text-align: center;
	font: 14px 'Exo 2', Helvetica, Verdana, Arial, sans-serif;
	font-weight: lighter;
	bottom: 0px;
	padding: 5px;
}

.navbar-custom {
    width: 1000px;
    min-width: 1000px;
    margin: 0px auto;
}

.heading-bolder {
	font-family: Helvetica, Arial, sans-serif;
	font-weight: bold;
	font-size: 18px;
	padding-left: 10px;
}

.equipment {
	position: absolute;
	left: 0px;
}

.mainimage {
	position: absolute;
	left: 100px;
}

/* Match the original village baseline, cropping 32px of foreground below
 * the header to reveal more sky above the hills. */
.header-parallax {
	position: relative;
	overflow: hidden;
}

.header-parallax .mainimage {
	top: 0;
	width: 900px;
	height: 235px;
	transform: translate3d(0, var(--valley-offset, 0px), 0);
}

.header-parallax .mainimage img {
	position: absolute;
	bottom: -32px;
	display: block;
	width: 100%;
	height: auto;
}

/* Nextgen-only equipment preference; retain the original header height. */
.header-no-equipment .equipment { display: none; }
.header-no-equipment .mainimage { left: 0; width: 100%; }
/* Move the larger image up within the taller header to expose more sky. */
.header-no-equipment .mainimage img { bottom: -34px; }
.header-no-equipment .pagetitle,
.header-no-equipment .pagesubtitle { left: 0; right: 0; text-align: center; }

/* Keep the township crop static when reduced motion is requested. */
@media (prefers-reduced-motion: reduce) {
	.header-parallax .mainimage { transform: none; }
}

.pagetitle {
	margin: 0;
	position: absolute;
	top: 30px;
	left: 125px;
	font: 94px Bowlby One SC, Verdana, Arial, Helvetica, sans-serif;
	/* Soft depth keeps the title legible over the valley photo. */
	text-shadow: 0 2.5px 7px rgba(15, 35, 50, 0.38);
	text-align: right;
	color: white; /* Older Browsers */
	color: rgba(255,255,255,0.9);
}

.pagesubtitle {
	position: absolute;
	top: 137px;
	left: 145px;
	font: 25px 'Exo 2', Verdana, Arial, Helvetica, sans-serif;
	/* A tighter, lighter shadow keeps the smaller lettering crisp. */
	text-shadow: 0 1.5px 3.5px rgba(15, 35, 50, 0.33);
	text-align: center;
	color: white; /* Older Browsers */
	color: rgba(255,255,255,0.8);
}

.pagedatetime {
	position: absolute;
	top: 155px;
	right: 60px;
	font: 10px sans-serif, Helvetica, Arial, Verdana;
	font-weight: normal;
	text-align: center;
	color: white; /* Older Browsers */
	color: rgba(255,255,255,0.7);
}

.pagefont {
	font: 14px Bowlby One SC, Verdana, Arial, Helvetica, sans-serif;
}

/* Compact single-line highlights below the full header. */
.header-summary {
 display: flex; align-items: center; justify-content: space-between;
 gap: 14px; width: 100%; min-height: 36px; padding: 8px 14px;
 background: linear-gradient(110deg, #337ab7, #286598);
 border-top: 1px solid #ffffff50; border-bottom: 1px solid #76bce6;
 color: #fff; font-family: 'Exo 2', Arial, sans-serif;
}
.header-readings { display: flex; align-items: center; gap: 12px; }
.header-reading { display: flex; align-items: center; gap: 5px; white-space: nowrap; }
/* Divider sits on the left of each reading after the first, so a hidden 3pm snapshot takes its divider with it. */
.header-reading + .header-reading { padding-left: 10px; border-left: 1px solid #ffffff30; }
.header-summary .reading-label { font-size: 10px; font-weight: 500; white-space: nowrap; color: #e0f1ff; }
.summary-value { display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.header-reading strong { font: 500 14px/1.2 'Exo 2', Arial, sans-serif; }
.summary-arrow { display: inline-block; font: 500 15px/1 Arial, sans-serif; color: #c4ecff; }
/* Wind bearing: circled arrow (inline SVG) rotated to the wind source; ring alone = calm, dimmed = unavailable. */
.summary-bearing { display: inline-flex; margin-left: 4px; line-height: 0; }
.summary-bearing svg { width: 15px; height: 15px; }
.summary-bearing[data-state="calm"] .bearing-arrow { display: none; }
.summary-bearing[data-state="unknown"] { opacity: 0.45; }
.summary-bearing[data-state="unknown"] .bearing-arrow { display: none; }
.summary-clock { margin-left: auto; display: flex; align-items: center; gap: 10px; text-align: right; }
/* The 3pm bell: outline = off, filled = on, dimmed = blocked; hidden until js/notify.nextgen.js knows the state. */
.summary-notify { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 12px; background: transparent; color: #e0f1ff; cursor: pointer; line-height: 0; }
.summary-notify svg { width: 15px; height: 15px; }
.summary-notify:hover, .summary-notify:focus-visible { background: #ffffff22; color: #fff; outline: none; }
.summary-notify .bell-fill { display: none; }
.summary-notify[data-state="on"] .bell-fill { display: block; }
.summary-notify[data-state="on"] .bell-outline { display: none; }
.summary-notify[data-state="on"] { color: #fff1bd; }   /* the recorded-value tint: this bell is about the 3pm record */
.summary-notify[data-state="blocked"] { opacity: 0.45; cursor: default; }
.summary-notify.busy { opacity: 0.6; cursor: progress; }
.summary-notify[hidden] { display: none; }
/* Clock matches the reading labels (same face, size, weight and tint). */
.header-summary .pagedatetime { position: static; margin: 0; color: #e0f1ff; font: 500 10px/1.4 'Exo 2', Arial, sans-serif; text-align: right; white-space: nowrap; }
.header-summary #clock-time { font-variant-numeric: tabular-nums; } /* fixed-width digits so the ticking seconds don't shift the clock */
/* Recorded, not live: the 3pm record and today's Max share one tint so the four live readings stay white. */
.summary-snapshot .reading-label, .summary-snapshot strong,
.summary-max .reading-label, .summary-max strong { color: #fff1bd; }
.header-reading .snapshot-pending { font-size: 11px; }
.header-reading[hidden] { display: none; }

.heading {
	margin: 0;
	color: white;
	text-align: left;
	font: 18px Arial, Helvetica, sans-serif;
	letter-spacing: 1px;
	font-weight: bold;
	padding: 0px;
	text-shadow: black 1px 1px;
}

.updated {
	color: DeepSkyBlue;
	text-align:right;
	font: 10px 'Roboto', sans-serif;
	letter-spacing: 0px;
	font-weight: lighter;
	text-shadow: none;
}

.shorter {
	padding: 5px 5px 5px 10px;
}

.rbutton {
    padding: 1px;
    float: right;
}

.section {
    font: 18px 'Exo 2', Verdana, Arial, Helvetica, sans-serif;
    border-left: 1px dashed steelblue;
    border-right: 1px dashed steelblue;
    border-bottom: 1px dashed steelblue;
    margin-left: auto;
    margin-right: auto;
    width: 900px;
}

.location {
	font: 18px 'Roboto', Verdana, Arial, Helvetica, sans-serif;
	font-weight: 100;
	text-align: center;
	letter-spacing: 1px;
}

table {
	margin-left: auto;
	margin-right: auto;
	overflow: auto;
}

.table-morecondensed > thead > tr > th,
.table-morecondensed > tbody > tr > th,
.table-morecondensed > tfoot > tr > th,
.table-morecondensed > thead > tr > td,
.table-morecondensed > tbody > tr > td,
.table-morecondensed > tfoot > tr > td {
	padding: 2px 1px 0px 10px;
}

/* Match the original (BS3) page's compact rows. BS5's base .table applies larger
   cell padding via `.table > :not(caption) > * > *`; this higher-specificity
   rule pins the values tables to the same 2px geometry as the original page and
   drops BS5's trailing table margin. */
.table.values > :not(caption) > * > * { padding: 2px 1px 1px 10px; vertical-align: top; line-height: 1.42857143; border-bottom-color: #ddd; }
/* Drop the last row's bottom border so no stray grey line floats above the
   card's bottom padding (BS5 borders every cell's bottom; BS3 didn't). */
.table.values > tbody > tr:last-child > *,
.table.values > tr:last-child > * { border-bottom-width: 0; }
.table.values { margin-bottom: 0; }

table.graphs {
	border: 2px dotted black;
	margin:0;
}

/* Weather Station Location: float the map + photo evenly in the card. The row
   is a flex line with space-evenly, so the gaps left, between and right are
   equal (~20px in the fixed 976px card body); the vertical padding matches that
   gap so the pair sits balanced on all sides. The cells drop the global
   td { width: 50% } so each hugs its image. */
table.maps, table.maps tbody { display: block; width: 100%; margin: 0; padding: 0; overflow: visible; }
table.maps tr { display: flex; justify-content: space-evenly; align-items: center; padding: 20px 0; }
table.maps td { display: block; width: auto; padding: 0; overflow: visible; }   /* visible: the global td clip would cut off the hover halo */
.card-body:has(> table.maps) { padding-bottom: 0; }
table.maps .photos { overflow: hidden; }
/* The township photo is 275x200 in a 275x220 box: crop, don't stretch. */
table.maps .loc-gallery img { object-fit: cover; }

table.values th, td {
	/* padding: 2px; */
	width: 50%;
	font: 17px 'Roboto', sans-serif;
	font-weight: lighter;
	overflow: hidden;
}

td.reading {
	font-weight: 500;
	letter-spacing: 1px;
	padding-left: 10px;
	/* background: #e0e0e0; */
}

td.value, td.fixed {
	color: black;
}

/* Values that read mid-sentence: the changeover is served as "Midnight" for headings;
   "4 mm since midnight" wants lowercase, on first paint and JS refresh. */
td.value .lc { text-transform: lowercase; }

td.estimate {
	color: #555555;   /* calculated (not sensed) values: wind chill, dew point, heat index, wet bulb, cloud base — dark grey, 7.5:1 on white */
}

td.forecast {
	color: black;   /* neutral, like every other reading — the forecast is information, not a warning (was red) */
}

/* Seven-day outlook strip (includes/outlook.modern.inc): edge to edge under
   Current Weather Conditions, one cell per local day with hairlines between.
   Reads as a continuation of the table — same Roboto, same weights — with no label
   of its own. Cells and the strip carry [hidden] when the daemon has no day to show. */
.outlook { display: flex; border-top: 1px solid #ddd; padding: 6px 8px 4px; }
.outlook[hidden] { display: none; }
.outlook-day { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 4px 2px; border-left: 1px solid #e6e6e6; font: 300 14px 'Roboto', sans-serif; line-height: 1.2; color: #000; }
.outlook-day[hidden] { display: none; }
.outlook-day:first-child { border-left: 0; }
.outlook-day .d { font-weight: 500; letter-spacing: .5px; }
.outlook-day.today .d { color: #337ab7; }
/* The day's glyph is sized to the Station Forecast icon above it (the table's 17px), as on modern;
   min-height keeps a day with no glyph aligned. */
.outlook-day .ic { font-size: 17px; min-height: 1em; margin: 6px 0 5px; color: #2a4d6e; }
.outlook-day .c { font-size: 12px; color: #444; white-space: nowrap; }
.outlook-day .p { margin-top: 4px; white-space: nowrap; }   /* the value never breaks mid-figure on a narrow cell */
/* How much, beside how likely: the ensemble's median, in the same voice as the chance */
.outlook-day .p .mm { font-size: 11px; color: #777; margin-left: 4px; }
.outlook-day .p .mm[hidden] { display: none; }
.outlook-day .p i { font-size: 12px; margin-right: 2px; }
/* Chance of rain: dry grey, possible blue, likely a stronger blue */
.outlook-day .p.r0 { color: #6a7a88; }
.outlook-day .p.r1 { color: #2a72b5; }
.outlook-day .p.r2 { color: #0b4f8a; font-weight: 500; }
.outlook-day .p.s1 { color: #4a6b8a; }                       /* snow on the hills above the grid cell */
.outlook-day .p.s2 { color: #1f4e79; font-weight: 500; }     /* snow at the grid cell itself */
/* Wind: the rose as a dial. The needle points where the wind blows to and the ring
   fills with the day's strongest gust, against the same 80 km/h ceiling as the bars —
   no figure on the face, every number in the cell's tooltip. One size for every band:
   the ring and its colour carry the strength, so the cells stay on one baseline. */
.outlook-day .w { margin-top: 4px; line-height: 1; }
.outlook-day .dial { display: block; width: 44px; height: 44px; }   /* one size: the ring says the strength */
.outlook-day .dial .track { fill: none; stroke: #e6e6e6; stroke-width: 2.6; }
.outlook-day .dial .arc { fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; }
.outlook-day .dial .ndl { stroke: currentColor; stroke-width: 1.6; fill: currentColor; }
/* The compass face is chrome, not data: the quarter ticks and the cardinals stay pale
   so the coloured ring and needle read first. */
.outlook-day .dial .tick { stroke: #c2c2c2; stroke-width: 1.5; }
.outlook-day .dial .card { fill: #bdbdbd; font: 500 8.5px 'Roboto', sans-serif; text-anchor: middle; dominant-baseline: central; }

/* The day's own shape, on hover (and on focus, so a keyboard reaches it): what falls
   and when, what the wind does and when — both from the daemon's three-hour profiles.
   The cell stays quiet; the panel carries the detail and the figures. */
.outlook-day { position: relative; }
.outlook-day:focus { outline: none; }
.outlook-day:focus-visible { outline: 2px solid #337ab7; outline-offset: -2px; }
.outlook-day .pop {
	position: absolute; bottom: calc(100% - 6px); left: 50%; transform: translateX(-50%);
	z-index: 5; min-width: 240px; width: min-content; padding: 8px 10px 7px; text-align: left;   /* 240px holds the longest heading and its pill; wider only if a font needs it, so nothing spills out */
	background: #fff; border: 1px solid #ccc; border-radius: 6px;
	box-shadow: 0 6px 18px rgba(0, 0, 0, .16);
	font: 300 12px 'Roboto', sans-serif; color: #333;
	visibility: hidden; opacity: 0;
}
.outlook-day:hover .pop, .outlook-day:focus-within .pop { visibility: visible; opacity: 1; }
.outlook-day:first-child .pop { left: 0; transform: none; }       /* the ends stay inside the card */
.outlook-day:last-child .pop { left: auto; right: 0; transform: none; }
.outlook-day .pop .ph { display: flex; justify-content: space-between; align-items: center; gap: 8px; white-space: nowrap; font-weight: 500; font-size: 13px; color: #000; margin-bottom: 5px; }
/* The one word that says the panel is a forecast, not a reading: a quiet outlined tag */
.outlook-day .pop .tag { flex: none; font-size: 11px; font-weight: 400; line-height: 1.3; color: #6a7a88; border: 1px solid #c3ccd4; border-radius: 9px; padding: 1px 7px; }
.outlook-day .pop .pr { display: flex; justify-content: space-between; align-items: baseline; margin-top: 6px; }
.outlook-day .pop .pl { font-weight: 500; color: #555; }
.outlook-day .pop .pv { color: #000; white-space: nowrap; }
.outlook-day .pop .pb { display: block; width: 100%; height: 24px; margin: 3px 0 1px; }   /* 216 x 24, one unit a pixel, so the hatching stays square */
/* A model's bars are hatched, never solid: each bar a fine outline in its band's colour
   round its band's pattern (the defs in outlook.*.inc) */
.outlook-hatch { position: absolute; width: 0; height: 0; overflow: hidden; }
.outlook-day .pop .pb rect { stroke-width: 1; shape-rendering: crispEdges; }
.outlook-day .pop .pb rect.dry { fill: #e6e6e6; stroke: none; }
.outlook-day .pop .pb rect.wet { fill: url(#wxhatch-wet); stroke: #2a72b5; }
.outlook-day .pop .pb rect.g0 { fill: url(#wxhatch-g0); stroke: #9aa3ab; }
.outlook-day .pop .pb rect.g1 { fill: url(#wxhatch-g1); stroke: #6b7c8a; }
.outlook-day .pop .pb rect.g2 { fill: url(#wxhatch-g2); stroke: #a15c00; }
.outlook-day .pop .pb rect.g3 { fill: url(#wxhatch-g3); stroke: #b02a37; }
.outlook-day .pop .pt { font-size: 11px; color: #666; }
.outlook-day .w.g0 { color: #8a8a8a; }                      /* under 30 km/h */
.outlook-day .w.g1 { color: #5f5f5f; }                      /* to 59 km/h — a darker grey than g0, not black */
.outlook-day .w.g2 { color: #a96b08; font-weight: 500; }    /* to 89 km/h */
.outlook-day .w.g3 { color: #b83843; font-weight: 500; }    /* 90 km/h and over */
/* Next 24 hours (includes/forecast.nextgen.inc): the top of the Long Range Outlook card.
   One column per hour under a label column carrying each row's unit, same Roboto as the
   value tables, a firmer rule where a new day starts. Scrolls sideways on a phone. */
.next24 { overflow-x: auto; padding: 4px 8px 4px 10px; }
.next24[hidden] { display: none; }
.next24-table { width: 100%; table-layout: fixed; border-collapse: collapse; font: 300 13px 'Roboto', sans-serif; line-height: 1.35; color: #000; }
.next24-table th[scope="row"] { width: 118px; text-align: left; font-weight: 300; font-size: 12px; color: #555; white-space: nowrap; padding: 2px 4px 2px 0; position: sticky; left: 0; z-index: 1; background: #fff; }
.next24-table td { font-size: 13px; text-align: center; white-space: nowrap; padding: 2px 0; }   /* sized here: the page-wide td rule is 17px */
.next24-table td[hidden] { display: none; }
.next24-table tr:nth-child(even) > * { background: #f7f7f7; }   /* striped like the value tables, the pinned label too */
.next24-table td.nd { border-left: 1px solid #c8c8c8; }          /* midnight: a new day starts here */
.next24-table tr.hr td { font-weight: 500; font-size: 12px; color: #333; }
.next24-table tr.hr th + td { color: #337ab7; }                  /* Now, in the outlook's Today blue */
.next24-table tr.sky td { padding: 3px 0; }
.next24-table tr.sky .ic { font-size: 18px; color: #2a4d6e; }
.next24-table .wd { display: inline-block; font-size: 10px; margin-right: 2px; color: #555; }   /* inline-block so the arrow can turn */
.next24-table .wd[hidden] { display: none; }
/* Current Weather Conditions wind rows: the summary strip's circled-arrow vane between the bearing and the wind's name, turned to point into the wind */
.table.values .wind-arrow { display: inline-flex; margin: 0 3px; line-height: 0; vertical-align: -3px; color: #6b7280; }
.table.values .wind-arrow svg { width: 15px; height: 15px; }
.table.values .wind-arrow[hidden] { display: none; }
.next24-table tr.level td, .next24-table tr.gust td { color: #444; }
/* Chance of rain in the outlook's bands; precipitation fades when dry, darkens as snow */
.next24-table .r0 { color: #6a7a88; }
.next24-table .r1 { color: #2a72b5; }
.next24-table .r2 { color: #0b4f8a; font-weight: 500; }
.next24-table .z { color: #aaa; }
.next24-table .wet { color: #2a72b5; font-weight: 500; }
.next24-table .sn { color: #1f4e79; font-weight: 500; }

td.title {
	text-align: center;
	background: #e0e0e0;
}

td.gtitle {
	text-align: center;
	background: #e0e0e0;
	width: 33%;
}

.chart-gtitle {
	text-align: center;
	background: #e0e0e0;
	font: 17px 'Roboto', sans-serif;
	font-weight: lighter;
	line-height: 1.42857143;
	padding: 2px 1px 1px 10px;
	border-bottom: 1px solid #ddd;
}

.chart-legend {
	box-sizing: border-box;
	display: flex;
	justify-content: flex-end;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px 22px;
	margin: 0;
	padding: 9px 12px 2px;
	color: #333;
	font-size: 12px;
	line-height: 18px;
}

td.gauge {
	width: 33%;
}

/* Gauge / small-chart cells carry their own title bar (div.gtitle) instead of a
   separate <tr> of td.gtitle, so the cells can wrap on a phone. The cell padding
   moves onto .gauge-body and the title reproduces the old td.gtitle geometry
   exactly: BS cell padding, 17px Roboto, 1px #ddd rule. It carried #d5d5d5 for a
   while — the old row was striped (BS5 5% black inset over #e0e0e0) and that tint
   was baked in when the striping went — but on 19 Sep 2026 every sub-heading bar
   on the page settled on the one grey, #e0e0e0, so the tint is gone. The 1px
   rules BETWEEN the gauge cells stay #d5d5d5: a rule a shade darker than the bar
   it runs under is a rule you can still see. */
.table.values > :not(caption) > * > td.gauge { padding: 0; }
td.gauge > .gtitle {
	display: block;
	text-align: center;
	background: #e0e0e0;
	font: 17px 'Roboto', sans-serif;
	font-weight: lighter;
	line-height: 1.42857143;
	padding: 2px 1px 1px 10px;
	border-bottom: 1px solid #ddd;
}
td.gauge > .gauge-body { padding: 2px 1px 1px 10px; }
/* Last 24-Hour Charts: every chart fills its box (charts.nextgen.js measures
   it), with the unit in the title bar instead of a rotated y-axis label. Fixed
   table layout so a drawn canvas can't push its column wider than a third.
   --chart-ygutter is the y tick-label gutter; the phone rules shrink it. */
#graph_data table { table-layout: fixed; }
#graph_data td.gauge > .gauge-body { padding: 2px 10px 1px 4px; }
#bigchart { --chart-ygutter: 30px; }
#hchart, #pchart, #wchart { --chart-ygutter: 26px; }
/* Right-aligned legend keys mirror the two measured traces. */
.chart-legend .ec-leg-series { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px 20px; }
.chart-legend .ec-leg { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; font-weight: normal; }
.chart-legend .ec-leg-line { width: 24px; border-top: 2px solid; }
.chart-legend .ec-leg-dashed { border-top-style: dashed; }
/* Unit in the title bar for the 24h charts and the current gauge readings (data-unit on the title) */
.chart-gtitle[data-unit]::after, td.gauge > .gtitle[data-unit]::after { content: " (" attr(data-unit) ")"; }
/* Gauge cells: one height for both rows, each gauge centred both ways in its cell
   (the dials, rose, column and cloudbase have different natural heights). 256px leaves
   room above a dial for a range value at the top of its rim. */
#gauge_data td.gauge > .gauge-body { display: flex; align-items: center; justify-content: center; height: 256px; box-sizing: border-box; padding: 0; }
#gauge_data .gauge-box { margin: 0 !important; }
/* Vertical rules between the gauge cells, a shade darker than the title bar (trial; the
   phone grid draws the same lines). (Modern and nextgen alike; original is untouched.) */
#gauge_data td.gauge + td.gauge { border-left: 1px solid #d5d5d5; }

.photos a img {
	border: none;
}

/* Location map + photo hover: a card-blue ring with a bright halo around the image
   instead of fading it (the box is the .photos div, hugging a block img). */
.photos img { display: block; }
.photos {
	border-radius: 2px;
	transition: box-shadow .2s ease;
}
.photos:hover,
.photos:has(a:focus-visible) {
	box-shadow: 0 0 0 2px #428bca, 0 0 16px 4px rgba(66, 139, 202, .7);
}


/* ============================================================
 * Bootstrap 5 components, styled to match the old BS3 look
 * ------------------------------------------------------------
 * The page uses native BS5 .card / .nav-tabs / .alert / .table.
 * BS5 dropped the .panel component and renamed grid/utility
 * classes, so the rules below:
 *   - make .card look exactly like the old .panel-primary
 *     (blue header, same border/radius/margin) and sit FLUSH
 *     (no card-body padding) like the old panel > row-fluid;
 *   - restore the .badge pill (card-blue fill);
 *   - reproduce the satellite thumbnail grid (col-xs-3 /
 *     thumbnail / caption) and the pull-left/right helpers that
 *     the shared satellite/*.inc and location.inc still emit.
 * ============================================================ */

/* Cards == old primary panels. The resting shadow matches the page title's
   drop shadow so the cards sit with the same soft depth as the header. */
:root { --card-shadow: 0 2.5px 7px rgba(15, 35, 50, 0.38); }
.card {
	margin-bottom: 20px;
	background-color: #fff;
	border: 2px solid #337ab7;
	border-radius: 8px;
	box-shadow: var(--card-shadow);
}
.card > .card-header {
	color: #fff;
	background-color: #337ab7;
	border-bottom: 1px solid #337ab7;
	/* Overlap the 2px frame and use the outer 8px radius so the header's blue
	   paints over the border at the corners — kills the sub-pixel white seam
	   where the same-blue border meets the header. (overflow:hidden would fix it
	   too but would clip anything a card lets overhang, e.g. chart tooltips.) */
	margin: -2px -2px 0 -2px;
	border-radius: 8px 8px 0 0;
}
/* Like the old panel > row-fluid: content is flush to the sides, with a small
   bit of breathing room at the bottom of each boxed section. */
.card > .card-body {
	padding: 0 0 6px;
}
.card > .card-footer {
	background-color: #f5f5f5;
	border-top: 1px solid #ddd;
	border-radius: 0 0 6px 6px;
}

/* Card collapse (js/cards.nextgen.js): a hairline chevron at the right of each
   section header, design B of the 27 Sep 2026 options canvas. The whole header
   toggles; the chevron is the real <button> for keyboard and screen readers.
   Cards open and shut in one frame (no height animation, like the tabs); only
   the chevron turns. The header padding is set without JS so headings never
   rewrap when the button arrives. */
main.container > .card[data-card] > .card-header { position: relative; padding-right: 34px; }
.card.has-toggle > .card-header { cursor: pointer; }
.card-toggle {
	position: absolute;
	top: 50%;
	right: 4px;
	width: 26px;
	height: 26px;
	margin-top: -13px;
	padding: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: #fff;
	background: transparent;
	border: 0;
	border-radius: 4px;
	opacity: 0.7;
	line-height: 0;
	cursor: pointer;
}
.card-toggle svg { transition: transform 120ms ease; }
.card.has-toggle > .card-header:hover > .card-toggle,
.card-toggle:focus-visible { opacity: 1; }
.card-toggle:focus-visible { outline: 2px solid #bfe3ff; outline-offset: -2px; }
/* Collapsed: chevron points down, body and footer go, and the header takes the
   whole frame (overlapping the bottom border too) with all four corners rounded. */
.card.is-collapsed > .card-header > .card-toggle svg { transform: rotate(180deg); }
.card.is-collapsed > .card-body,
.card.is-collapsed > .card-footer { display: none; }
.card.is-collapsed > .card-header { margin-bottom: -2px; border-radius: 8px; }
@media (prefers-reduced-motion: reduce) { .card-toggle svg { transition: none; } }

/* Neutral "default" card (Daily 3pm snapshot) */
.card-muted { border-color: #ddd; }
.card-muted > .card-header {
	color: #333;
	background-color: #f5f5f5;
	border-bottom: 1px solid #ddd;
}

/* Grey sub-heading bar inside a section card (Daily 3pm snapshot): a flat
   grey strip + bottom rule, no nested border/box. Sits flush in .card-body. */
/* Section sub-heading bar (Daily Record Reading snapshot line): same face as the
   gauge / chart title bars (17px light Roboto, #d5d5d5, 1px #ddd rule), and now
   centred like them. It was left-aligned to keep the right of the bar free for a
   refresh timestamp (#snapshot_time) that nothing ever wrote to; nextgen drops
   that slot, so the line centres in the bar. Modern still carries it. */
.card-subhead {
	color: #333;
	background: #d5d5d5;
	text-align: center;
	font: 17px 'Roboto', sans-serif;
	font-weight: lighter;
	line-height: 1.42857143;
	border-bottom: 1px solid #ddd;
	padding: 2px 10px 1px 10px;
}

/* Value pill (BS5 badges are transparent without a bg utility). Outlined in the
   card blue rather than filled: a solid fill repeated the card-header blue down
   the column, so every reading read as a miniature title bar. The outline keeps
   the pill distinct at a fraction of the weight; tabular figures keep digits
   aligned across rows. 1px, not the card frame's 2px — 2px shipped first and
   still read too heavy on the page. Geometry is unchanged from the filled pill
   — 1px border + 3px/8px padding is the same 21px x outer width as the old
   4px/9px padding — so row heights and pill widths do not move. #2a6496 on
   white is 6.3:1. */
.badge {
	display: inline-block;
	min-width: 10px;
	padding: 3px 8px;
	font-size: 13px;
	font-weight: 600;
	line-height: 1;
	color: #2a6496;
	text-align: center;
	white-space: nowrap;
	vertical-align: middle;
	background-color: #fff;
	border: 1px solid #337ab7;
	border-radius: 10px;
	font-variant-numeric: tabular-nums;
	/* `vertical-align: middle` centres on the x-height, not the line box, so the
	   pill sits low in the 17px row; lift it onto the optical centre. */
	position: relative;
	top: -2px;
}

/* Satellite thumbnail grid (shared satellite/*.inc emit BS3 classes) */
.sat-row { padding: 15px; }
.sat-row::after { content: ""; display: table; clear: both; }
.col-xs-3 {
	position: relative;
	float: left;
	width: 25%;
	min-height: 1px;
	padding-right: 15px;
	padding-left: 15px;
}
.thumbnail {
	display: block;
	padding: 4px;
	margin-bottom: 20px;
	line-height: 1.42857143;
	background-color: #fff;
	border: 1px solid #ddd;
	border-radius: 4px;
	transition: border .2s ease-in-out;
}
.thumbnail > img { display: block; max-width: 100%; height: auto; margin: 0 auto; }
.thumbnail .caption { padding: 9px; color: #333; }
.thumbnail .caption p { font-size: 11px; margin: 0; }

/* Float helpers removed in BS5 (shared includes still use them) */
.pull-left  { float: left  !important; }
.pull-right { float: right !important; }

/* Weather Icons — two problems with the cdnjs build, fixed here:
 *   1. cdnjs weather-icons.min.css applies the 'weathericons' font-family ONLY
 *      via the base .wi class; the .wi-* rules just set the glyph codepoint.
 *      The site's markup uses the modifier class alone (wi-sunrise, wi-day-sunny,
 *      wi-wind-*) with no .wi, so the glyph renders in the page font as a broken
 *      (italic, since <i>) box. We apply the font to any wi-* class below.
 *   2. We declare @font-face ourselves against the ABSOLUTE cdnjs font URLs, so
 *      the font load can't depend on the cdnjs CSS's relative ../font/ paths.
 *      Still served from the cdnjs remote — just addressed explicitly. */
@font-face {
	font-family: 'weathericons';
	src: url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.12/font/weathericons-regular-webfont.woff2') format('woff2'),
	     url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.12/font/weathericons-regular-webfont.woff') format('woff'),
	     url('https://cdnjs.cloudflare.com/ajax/libs/weather-icons/2.0.12/font/weathericons-regular-webfont.ttf') format('truetype');
	font-weight: normal;
	font-style: normal;
	font-display: swap;
}
[class^="wi-"], [class*=" wi-"] {
	font-family: 'weathericons' !important;
	font-style: normal;
	font-weight: normal;
	line-height: 1;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* nav-tabs: BS5 defaults use a bright link blue (#0d6efd), black active text and
 * tighter padding/radius. Restore the original (BS3) site look: muted link blue,
 * grey active text, 10px/15px padding, 4px top radius. Applies to the Yearly
 * Extremes and Satellite tab strips. */
.nav-tabs { --bs-nav-tabs-link-active-color: #555555; }
.nav-tabs .nav-link {
	color: #006699;
	padding: 10px 15px;
	border-radius: 4px 4px 0 0;
}
.nav-tabs .nav-link.active,
.nav-tabs .nav-link.active:hover,
.nav-tabs .nav-link.active:focus {
	color: #555555;
}

/* The divider spans the scroll arrows as well as the tab viewport. */
.tabstrip { border-bottom: 1px solid #d5e0e9; }
.tabstrip :is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) { border-bottom: 0; }

/* Refined Classic: nextgen daily, yearly, astronomy and 3pm snapshot tabs. */
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) {
	gap: 3px;
	padding: 6px 6px 0;
	border-bottom: 1px solid #d5e0e9;
}
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) .nav-link {
	font: 500 15px/1.4 'Roboto', Arial, sans-serif;
	font-variant-numeric: tabular-nums;
	color: #337ab7;   /* inactive tabs take the card blue */
	padding: 6px 14px;
	margin: 0;
	background: transparent;
	border: 1px solid transparent;
	border-radius: 6px 6px 0 0;
}
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) .nav-link:hover {
	color: #286394;
	background: #f2f2f2;
}
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) .nav-link.active,
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) .nav-link.active:hover,
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) .nav-link.active:focus {
	color: #286394;
	background: #f2f2f2;
	border-color: #d5e0e9;
	box-shadow: 0 -2px 4px #d5e0e9;
	border-bottom-color: #f2f2f2;
}
:is(#yearlyTabs, #astroTabs, #dayTabs, #snapTabs) .nav-link:focus-visible {
	outline: 2px solid #286394;
	outline-offset: -3px;
}

/* Tabs switch in one frame: Bootstrap fades the panes (a 150 ms blank gap) and
   crossfades the tab colours and borders while the shadow jumps, which flickers. */
.tab-content > .tab-pane.fade { transition: none; opacity: 1; }
.nav-tabs .nav-link { transition: none; }

/* Chevron tab strip (.tabstrip): a nav-tabs row that scrolls sideways when it
 * does not fit, with ‹ › buttons and edge fades that show only while there is
 * more to see. Used by the Yearly Extremes years (ytabs.nextgen.inc) and the
 * Astronomical Information tabs (astro.nextgen.inc); each include wires its own
 * buttons (update on scroll / resize / load / shown.bs.tab). */
.tabstrip { position: relative; display: flex; align-items: center; }
.tabstrip-viewport { position: relative; flex: 1 1 auto; min-width: 0; }
.tabstrip-scroll { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; -ms-overflow-style: none; }
.tabstrip-scroll::-webkit-scrollbar { display: none; }
.tabstrip-scroll .nav-tabs { display: flex; flex-wrap: nowrap; white-space: nowrap; }
.tabstrip-scroll .nav-tabs > li { flex: 0 0 auto; }
.tabstrip-arrow { flex: 0 0 auto; width: 28px; border: none; background: transparent; color: #999; font-size: 20px; line-height: 1; cursor: pointer; padding: 0 0 8px; }
.tabstrip-arrow:hover { color: #428bca; }
.tabstrip-arrow[disabled] { color: #ddd; cursor: default; }
.tabstrip-viewport::before, .tabstrip-viewport::after { content: ""; position: absolute; top: 0; bottom: 1px; width: 28px; pointer-events: none; opacity: 0; transition: opacity .2s; z-index: 2; }
.tabstrip-viewport::before { left: 0; background: linear-gradient(to right, #fff, rgba(255,255,255,0)); }
.tabstrip-viewport::after { right: 0; background: linear-gradient(to left, #fff, rgba(255,255,255,0)); }
.tabstrip-viewport.can-left::before { opacity: 1; }
.tabstrip-viewport.can-right::after { opacity: 1; }

/* Sparklines: ECharts (SVG), drawn by includes/charts.nextgen.js into these
 * fixed boxes (replaces jquery.sparkline / @fnando/sparkline). */
.tempsparkline, .humidsparkline, .barosparkline,
.dewptsparkline, .windsparkline, .rainsparkline {
	display: inline-block;
	vertical-align: middle;
	width: 144px;
	height: 28px;       /* 20px of drawing + 4px above and below for the hover line (SPARK_EXT) */
	margin: -4px 0;     /* ...taken back out, so the row still sees a 20px box */
}
/* rainfall bars are wider (like the original page) so they're not razor-thin */
.rainsparkline { width: 240px; }

/* shared hover tooltip (the month card's bars; the sparklines set the same look in ECharts) */
.sparkline-tooltip {
	position: fixed;
	z-index: 1080;
	pointer-events: none;
	background: rgba(0,0,0,0.8);
	color: #fff;
	font: 12px 'Roboto', Arial, sans-serif;
	padding: 2px 6px;
	border-radius: 3px;
	white-space: nowrap;
}

/* baguetteBox caption styled like lightbox2: a bar flush to the BOTTOM of the
   image and exactly the IMAGE's width (not the viewport). The figure is a centred
   flex column that shrink-wraps to the image (width:fit-content), so the caption
   (a stretched flex item) matches the image width and sits with no gap.
   column-reverse because baguetteBox outputs the <figcaption> before the <img>.
   The library's inline-block :before centring helper is disabled so our flex
   column can centre the image+caption group itself. !important beats library CSS. */
#baguetteBox-overlay .full-image:before { display: none !important; }
#baguetteBox-overlay .full-image figure {
	display: flex !important;
	flex-direction: column-reverse !important;
	align-items: stretch !important;
	justify-content: center !important;
	height: 100% !important;
	width: -moz-fit-content !important;
	width: fit-content !important;
	max-width: 100% !important;
	margin: 0 auto !important;
}
#baguetteBox-overlay .full-image figure img {
	align-self: center !important;
	max-height: calc(100% - 38px) !important;
	max-width: 100% !important;
	display: block !important;
}
#baguetteBox-overlay .full-image figcaption {
	position: static !important;
	left: auto !important;
	bottom: auto !important;
	width: auto !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 5px 10px !important;
	box-sizing: border-box !important;
	background: rgba(0,0,0,0.8) !important;
	color: #fff !important;
	font: 14px/1.35 'Roboto', Arial, sans-serif !important;
	text-align: center !important;
}

/* ---- Dials: Temperature, Humidity, Barometer (gauges.nextgen.inc/.js) ----------
   Each ECharts dial is laid out on a square box (--rg, set by gauges.nextgen.js when
   the cell is narrower than 220px). Its canvas reaches 40px either side and 16px
   above the box (HEAD in gauges.nextgen.js) so today's range values fit round the rim. */
.rg-wrap { position: relative; width: var(--rg, 220px); height: var(--rg, 220px); margin: 8px auto 0; }
.rg-dial { position: absolute; left: -40px; top: -16px; width: calc(100% + 80px); height: calc(100% + 16px); }
/* ---- Rainfall: upright column + zone strip + scale, the reading under it ---- */
.rain-wrap { position: relative; width: 60px; margin: 8px auto 0; }   /* width set to the drawing by gauges.nextgen.js */
.rain-col { width: 100%; height: 184px; }
.rain-now { text-align: center; width: 160px; margin: 6px 0 0 -59px; font: 500 16px Roboto, Arial, sans-serif; color: #222; white-space: nowrap; }   /* centred on the drawing's body (column, strip, numbers); gauges.nextgen.js sets the exact offset from the numbers' width */

/* ============================================================
 * Card entrance ("gentle entrance", subtle preset)
 * ------------------------------------------------------------
 * js/reveal.nextgen.js (shared) adds .is-in once per card: cards on the
 * first screen at once, the rest as their top edge enters.
 * Hidden state is gated on html.reveal-ready (set inline in
 * <head>) so a no-JS visit shows everything. Cards fade in without
 * moving, leaving the chart/gauge canvases untouched.
 * ============================================================ */
.reveal-ready .page > .container > .card {
	opacity: 0;
	transition: opacity .5s ease-out;
}
.reveal-ready .page > .container > .card.is-in { opacity: 1; }
.reveal-ready .card.no-anim { transition: none !important; }   /* first-screen cards: no animation */

/* Reduced motion: static page, nothing hidden */
@media (prefers-reduced-motion: reduce) {
	.reveal-ready .page > .container > .card { opacity: 1; transition: none; }
}

/* ============================================================
 * Phone (html.phone)
 * ------------------------------------------------------------
 * Every rule is scoped to html.phone, which the head script in
 * otematata_nextgen.php sets (with a device-width viewport) when
 * the screen's shorter edge is under 768px. Desktop AND tablet
 * keep width=1000 (the page scaled to fit, as it always was), so
 * these rules never apply there and the fixed layout above is
 * the untouched base. A class rather than a width media query so
 * a rotated phone keeps this layout (the scripts refit to width).
 * The intent is to keep the desktop look (blue header/cards,
 * grey title bars, Roboto value tables) and restack it, not
 * restyle it. Chart / gauge / sparkline sizes are driven by
 * their scripts reading the container width (charts.nextgen.js,
 * gauges.nextgen.js); the CSS just gives them
 * a fluid box to measure.
 * ============================================================ */

/* Fluid page: the side gutters (borders.gif) only make sense beside 1000px. */
html.phone body { background-image: none; }
html.phone .page { min-width: 0; }
html.phone .navbar-custom { width: auto; min-width: 0; }
html.phone .section { width: auto; max-width: 900px; }

/* ---- Header: the desktop composition scaled to the screen width -------- */
/* Desktop is 1000 wide: title 94px (9.4vw) at top 30, subtitle 25px at top
   137, header 235 tall, image trimmed 34px at the foot. The same ratios in vw
   keep the title the same size relative to the page; the header is a little
   taller than pure proportion (30vw vs 23.5vw) so the subtitle stays legible
   at 2.4vw (9px on a 375 screen, one line, narrower than the title) and the
   clock has a corner. */
html.phone .header { height: 30vw; }
html.phone .header-parallax .mainimage { height: 100%; }   /* base fixes this at 235px */
/* Parallax headroom. Desktop has 140px of photo above its 235px header (60%)
   for the valley to drift through. At 100% width the phone photo is only 40vw
   tall, leaving 6.6vw — the effect topped out after a few px of scroll. Drawn
   at 128.5% width (centred) it is 51.4vw tall, giving 18vw of headroom: the
   same 60% of the 30vw header, so the drift feels the same. The visible crop
   is the central ~78% of the valley; the foot trim stays proportional. */
html.phone .header-no-equipment .mainimage img { width: 128.5%; left: -14.25%; bottom: -3.4vw; }
html.phone .pagetitle { top: 4.5vw; font-size: 9.4vw; }
html.phone .pagesubtitle { top: 16.2vw; font-size: 2.4vw; padding: 0 3vw; line-height: 1.3; white-space: nowrap; }   /* ~92% of the title's width, sitting just under it */
html.phone .summary-clock { position: absolute; top: 1.5vw; right: 2.5vw; margin: 0; z-index: 1; }
html.phone .summary-notify { width: 30px; height: 30px; color: rgba(255,255,255,0.9); filter: drop-shadow(0 1px 2px rgba(15,35,50,0.5)); }   /* finger-sized over the header image */
html.phone .header-summary .pagedatetime { color: rgba(255,255,255,0.9); text-shadow: 0 1px 2px rgba(15,35,50,0.5); }

/* ---- 1C. Summary bar: the one desktop line, swiped sideways ----------- */
/* Same markup and type as desktop. The readings strip scrolls horizontally
   with the scrollbar hidden and its right edge faded (mask) as a swipe hint.
   The bar itself stays unclipped so the clock (absolute, header corner) is
   neither scrolled nor masked. */
html.phone .header-summary { display: block; padding: 0; gap: 0; }
html.phone .header-readings {
	display: flex; flex-wrap: nowrap; gap: 10px; padding: 7px 10px;
	overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none;
	-webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent);
	        mask-image: linear-gradient(90deg, #000 calc(100% - 40px), transparent);
}
html.phone .header-readings::-webkit-scrollbar { display: none; }
html.phone .header-reading { flex: none; }
html.phone .header-reading + .header-reading { padding-left: 8px; }
html.phone .header-readings::after { content: ""; flex: none; width: 40px; }   /* room under the fade */
html.phone .summary-max, html.phone .summary-snapshot { display: none; }   /* desktop-only extras: the phone strip keeps the four live readings */

/* Card headings: a touch smaller so the long ones wrap cleanly. */
html.phone .heading { font-size: 13px; letter-spacing: 0; }   /* the longest ("Yesterday's Extremes (24-Hours Prior to Midnight)") fits a 375 screen on one line */

/* Value tables: smaller face, tighter padding, label column narrower. */
html.phone table.values th, html.phone td { font-size: 13px; }   /* one notch down from 14 to keep labels on one line */
html.phone .table.values > :not(caption) > * > * { padding: 3px 4px 2px 8px; }
html.phone .table.values td.reading { width: 42%; letter-spacing: 0; padding-left: 8px; }
html.phone .table.values td.value { width: 58%; }
/* Outlook strip: one line of five days (the sixth and seventh are hidden, not wrapped) */
html.phone .outlook { padding: 4px 4px 2px; }
html.phone .outlook-day:nth-child(n+6) { display: none; }
html.phone .outlook-day { padding: 4px 0; font-size: 12px; }
html.phone .outlook-day .ic { font-size: 13px; }   /* the phone's Station Forecast icon */
html.phone .outlook-day .c { font-size: 10px; }
html.phone .outlook-day .p .mm { font-size: 9px; margin-left: 2px; }
html.phone .outlook-day .w { font-size: 11px; }
html.phone .outlook-day .dial { width: 36px; height: 36px; }
html.phone .outlook-day .pop { display: none; }   /* no hover on a phone, and no room for it */
html.phone .outlook-day .sp { height: 20px; width: 86%; }
/* Next 24 hours: natural column widths, scrolled sideways under the pinned label column */
html.phone .next24 { padding: 4px 0 4px 8px; }
html.phone .next24-table { width: auto; table-layout: auto; }
html.phone .next24-table th[scope="row"] { width: auto; font-size: 11px; padding-right: 6px; }
html.phone .next24-table td { font-size: 12px; min-width: 30px; padding: 2px 1px; }
html.phone .next24-table tr.sky .ic { font-size: 16px; }
/* Scale the pill to the phone row: at 13px cells the desktop pill matches the label's own size and,
   at 21px, outgrows the 18.6px line box and sets the row height. 12px text on trimmed padding keeps
   the pill inside the line box, so the label leads the row again and row heights are unchanged. */
html.phone .badge { font-size: 12px; padding: 1px 7px; top: -1.5px; }   /* 1px outline absorbed into the padding: the 16px pill is unchanged */

/* Sparklines: narrower than desktop (144 / 240) so the reading and its trend
   share a line where they can; the script reads the box width when drawing.
   (120px line sparklines were tried — they fit, but read as too heavy.) The
   Current table is fixed-layout so the sparkline boxes don't pull width away
   from the label column under the browser's auto layout. */
html.phone .tempsparkline, html.phone .humidsparkline, html.phone .barosparkline,
html.phone .dewptsparkline, html.phone .windsparkline { width: 90px; }
html.phone .rainsparkline { width: 160px; }
html.phone #current_data table { table-layout: fixed; }

/* ---- Gauges: 2 across, 3 deep, desktop order ------------------------ */
/* Temp | Wind, Humidity | Rain, Barometer | Cloudbase. The table becomes a
   two-column grid of equal-height tiles: title bar at the top of each, gauge
   centred in the remaining space. The two round dials redraw at the fitted
   size (~165px); the 150px Temperature/Humidity/Rainfall boxes scale to fit
   below ~375px; the 90px Cloudbase is unchanged. The rules between tiles
   are a 1px grid gap over a title-bar-grey backing (the table's own cell
   borders are keyed to row positions that no longer match the visual grid). */
html.phone #gauge_data table { display: block; }
html.phone #gauge_data tr { display: contents; }
html.phone #gauge_data tbody { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: #d5d5d5; }   /* 1px rules both ways, a shade darker than the title bar */
html.phone #gauge_data td.gauge {
	display: flex; flex-direction: column; width: auto; max-width: none;
	background: #fff; border: 0 !important; box-shadow: none;
	padding: 0 !important;   /* beats the phone value-table cell padding, so the title bar fills the tile */
}
html.phone #gauge_data td.gauge > .gauge-body { flex: 1; display: flex; align-items: center; justify-content: center; padding: 10px 12px; height: auto; }
html.phone #gauge_data .gauge-box { margin: 0 !important; }
html.phone #gauge_data .rg-wrap { margin: 0; }

/* ---- 3B. Charts: all four stacked full width, shorter ---------------- */
/* Big chart 220px (with its range selector); small charts 100px.
   charts.nextgen.js reads the variables and sizes to the cell; --chart-fill
   also turns touch zoom off so the page scrolls over the charts. */
/* Insets as margins, not padding, at the same 4/10px insets as the small
   charts' .gauge-body, so the div is exactly the chart width. */
html.phone #bigchart { padding: 0 !important; margin: 5px 10px 14px 4px !important; --chart-fill: 1; --chart-height: 220px; --chart-ygutter: 24px; }
html.phone #graph_data table, html.phone #graph_data tbody { display: block; }
html.phone #graph_data tr { display: flex; flex-wrap: wrap; }
html.phone #graph_data td.gauge { flex: 0 0 100%; max-width: 100%; width: auto; box-sizing: border-box; padding: 0 !important; }   /* title bars span the card like the big chart's */
html.phone #graph_data td.gauge > .gauge-body { padding: 4px 10px 4px 4px; }
html.phone #hchart, html.phone #pchart, html.phone #wchart { --chart-fill: 1; --chart-height: 100px; --chart-ygutter: 22px; }   /* y tick labels only: fits "1010" at 9px */
html.phone #graph_data br { display: none; }

/* Satellite thumbnails: 4 across becomes 2 x 2. */
html.phone .sat-row { padding: 10px; }
html.phone .col-xs-3 { width: 50%; padding-left: 5px; padding-right: 5px; }

/* Tab strips: taller links for finger-sized targets (Google: >= 48px). */
html.phone .nav-tabs .nav-link { padding: 14px 12px; }
html.phone .tabstrip-arrow { width: 40px; height: 48px; padding: 0 0 6px; }   /* strip chevrons (years, astronomy): finger-sized like the tabs beside them */

/* ---- 4B. Location: the map alone, bleeding to the card edges ---------- */
html.phone table.maps, html.phone table.maps tbody, html.phone table.maps tr, html.phone table.maps td { display: block; width: 100%; }
html.phone table.maps { border-spacing: 0; padding: 0; margin: 0; }
html.phone table.maps tr { padding: 0; }   /* the desktop balance padding is not wanted on the edge-to-edge map */
html.phone table.maps td + td { display: none; }
html.phone table.maps img { display: block; width: 100%; height: auto; }
html.phone .card-body:has(> table.maps) { padding-bottom: 0; }

/* Footer text is centred and wraps; just ease the sides. */
html.phone .footer { padding: 5px 10px; font-size: clamp(8px, 2.3vw, 12px); }   /* small print, sized to the screen so the longest line (the disclaimer) never wraps: 8.6px on a 375 screen */
html.phone .footer .container-fluid { padding-left: 0; padding-right: 0; }   /* Bootstrap's 12px gutters were taking the disclaimer line to 331px of room; it needs 343 */
/* Location card footer caption ("This weather monitoring station is located in…"). */
html.phone .location { font-size: 14px; letter-spacing: .5px; }
