/* ==========================================================================
   app-design.css -- design tokens and components for the /app shell
   --------------------------------------------------------------------------
   Loaded once from header-mobile.php, which is included for any URI containing
   "/app" or "?app" (see header.php). It therefore styles both the shell
   (header bar, offcanvas menu, bottom bar) and the report markup that
   appcontent.php injects into it -- appcontent.php is fetched raw, without
   WordPress, so it cannot enqueue anything of its own.

   SCOPE
   Every rule is under .app-shell / .season-*, which are put on <html> by the
   inline script at the top of header-mobile.php. Nothing here can leak into
   the main website.

   SEASON
   .season-winter and .season-summer differ ONLY in the --app-accent-* tokens.
   Components never name a colour directly, so re-skinning a season means
   editing three values, not hunting through markup.

   Default season is date-derived (May 1 - Oct 1 = summer) and overridden by
   the visitor's Summer/Winter toggle, which is stored in localStorage.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Seasonal accents
   --------------------------------------------------------------------------
   One accent per season, deliberately chosen to clear 4.5:1 BOTH ways -- as
   text on white and as white text/icons on a filled bar -- so the same token
   can paint the header bar and a 13px label without a second variant:

     #006bb6 winter  5.55:1
     #4a7c37 summer  4.97:1

   Fernie's existing summer green (#589442, in trailreport-2026.css) is only
   3.66:1 and fails for small text, so it is kept as the bright/large-display
   variant rather than the accent.
   -------------------------------------------------------------------------- */

.season-winter {
	--app-accent:        #006bb6;
	--app-accent-dark:   #00538c;
	--app-accent-bright: #1a86d4;
	--app-accent-tint:   #e7f1f8;
}

.season-summer {
	--app-accent:        #4a7c37;
	--app-accent-dark:   #3a6029;
	--app-accent-bright: #589442;
	--app-accent-tint:   #eef4ea;
}


/* --------------------------------------------------------------------------
   2. Scale tokens -- identical in both seasons
   -------------------------------------------------------------------------- */

.app-shell {
	/* Type. One scale for every app page; components pick from it and never
	   hard-code a px size. --fs-hero is fluid so the big open/total counter
	   cannot overflow a narrow phone. */
	--fs-hero:   clamp(42px, 13vw, 60px);
	--fs-h1:     26px;
	--fs-h2:     22px;
	--fs-h3:     18px;
	--fs-body:   16px;
	--fs-small:  14px;
	--fs-label:  13px;
	--fs-micro:  12px;
	--fs-nano:   11px;   /* table column headers only -- four of them have to fit a 320px row */

	--lh-tight:   1.15;
	--lh-heading: 1.25;
	--lh-body:    1.6;

	--tracking-label: .08em;
	--tracking-title: .04em;

	/* Spacing -- 4px base */
	--sp-1: 4px;
	--sp-2: 8px;
	--sp-3: 12px;
	--sp-4: 16px;
	--sp-5: 24px;
	--sp-6: 32px;
	--sp-7: 48px;

	--radius:    10px;
	--radius-sm: 6px;

	/* Neutrals */
	--ink:        #2f2f2f;
	--ink-muted:  #6b6b6b;
	--ink-faint:  #9b9b9b;
	--rule:       #dcdcdc;
	--surface:    #ffffff;
	--surface-alt:#f5f7f8;

	/* Status -- meaning, not season. These never change with the toggle. */
	--status-open:    #45a45e;
	--status-closed:  #c2474c;
	--status-standby: #d9a441;
}


/* --------------------------------------------------------------------------
   3. Shell -- header bar, bottom bar, offcanvas menu
   --------------------------------------------------------------------------
   header-mobile.php's own <style> block sets these backgrounds to
   var(--app-accent, #006bb6); the fallback keeps the shell looking right if
   this file ever fails to load.
   -------------------------------------------------------------------------- */

.app-shell .mobile-header,
.app-shell .app-footer,
.app-shell #footer {
	background-color: var(--app-accent);
}

/* Safe areas.
 *
 * header-mobile.php handles the TOP inset (padding-top: env(safe-area-inset-top)
 * on .mobile-header) and does nothing at all for the bottom. On a notched
 * iPhone that is the wrong half: the home indicator strip is at the bottom, and
 * a bar pinned to bottom:0 puts its lower ~34px inside it -- which reads as the
 * footer sitting too low.
 *
 * Both bars now use min-height plus inset padding rather than a hard height.
 * That matters on the header too: with box-sizing:border-box a fixed height:60px
 * and padding-top:47px (an iPhone 13's top inset) leaves 13px for the icons.
 * The bug is latent today only because the page ships three competing
 * <meta name="viewport"> tags and the last one drops viewport-fit=cover, which
 * is what makes env() return 0. Fix the metas and the crush appears; this makes
 * both bars correct either way.
 */
.app-shell .mobile-header {
	height: auto;
	min-height: 60px;
}

.app-shell .app-footer,
.app-shell #footer.app-footer {
	height: auto;
	min-height: 60px;
	padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* Reserves room for the bar so the last row of content is not trapped behind
   it. Has to grow by the same inset or it under-reserves by exactly the height
   of the home indicator. */
.app-shell .footer-spacer {
	height: calc(70px + env(safe-area-inset-bottom, 0px));
}

/* The header is justify-content:space-between, so the last child sits flush
   against the screen edge with nothing to breathe against. */
.app-shell .mobile-header #install-btn {
	margin-right: var(--sp-3);
}

/* Bar icon size. The markup carries an inline font-size:30px on each Font
   Awesome glyph, so overriding it needs !important. 22.5px is 75% of that,
   set in one place for the top and bottom bars together. */
.app-shell .mobile-header i,
.app-shell .footer-link i {
	font-size: 22.5px !important;
}

/* Bottom-bar Trail Report icon. A PNG rather than a Font Awesome glyph --
   FA's fa-person-biking is a drop-bar road bike, which reads wrong for a
   mountain-bike resort.
   Points at a TRIMMED copy of the trail-table sprite. The original
   /img/icon-trailreport-green-bike.png is an 80x35 canvas with the bike art
   pushed into the right-hand 46px (33px of empty space on the left, 1px on
   the right) because that canvas is shared with the wider hiker+bike variant.
   Centring that file centres the empty space, not the bike.
   The filter paints the coloured sprite solid white so it matches the glyphs
   beside it; drop that line to show it in its original green. */
.app-shell .footer-link .footer-icon-img {
	height: 22.5px;
	width: auto;
	display: block;
	margin: 0 auto;
	filter: brightness(0) invert(1);
}

.app-shell .footer-link span {
	font-size: var(--fs-micro);
	letter-spacing: .01em;
}

/* "Full Site" — the way out of the app, pinned below the season menu in the
   offcanvas panel. Separated by a rule and set slightly quieter than the menu
   items above it: it is an escape hatch, not a destination competing with the
   resort content. */
.app-shell .app-fullsite-link {
	margin-top: var(--sp-5);
	padding-top: var(--sp-4);
	border-top: 1px solid rgba(255, 255, 255, 0.25);
}

.app-shell .app-fullsite-link a {
	display: block;
	color: #fff;
	font-size: var(--fs-small);
	letter-spacing: .04em;
	text-transform: uppercase;
	padding: 10px 8px;
	text-decoration: none;
	opacity: .85;
}

.app-shell .app-fullsite-link a:hover,
.app-shell .app-fullsite-link a:focus {
	color: #fff;
	opacity: 1;
	text-decoration: none;
}

/* Show/hide by season -- lets a template ship both variants of an icon and
   let CSS pick, instead of branching in PHP or JS. */
.season-winter .season-summer-only { display: none !important; }
.season-summer .season-winter-only { display: none !important; }


/* --------------------------------------------------------------------------
   3b. Home tile grid -- [app_tiles], see app-tiles.php
   --------------------------------------------------------------------------
   Replaces nine to sixteen flat PNGs per season that had their background
   colour and caption baked in. Colour now comes from --app-accent, so the grid
   follows the season for free; the artwork is transparent white line art and
   the caption is real text.
   -------------------------------------------------------------------------- */

.app-shell .app-tiles {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;              /* every tile the same height, not just per row */
	gap: var(--sp-2);
	padding: var(--sp-3);
}

/* Three across is tight below ~360px, where the longer captions start to
   wrap to three lines. */
@media (max-width: 359px) {
	.app-shell .app-tiles { grid-template-columns: repeat(2, 1fr); }
}

.app-shell .app-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--sp-3);
	min-height: 128px;
	padding: var(--sp-4) var(--sp-2);
	border-radius: var(--radius);
	background: var(--app-accent);
	color: #fff;
	text-decoration: none;
	text-align: center;
	transition: transform .12s ease, filter .12s ease;
}

.app-shell .app-tile:hover,
.app-shell .app-tile:focus-visible {
	color: #fff;
	text-decoration: none;
	filter: brightness(1.08);
}

.app-shell .app-tile:active {
	transform: scale(.97);
}

.app-shell .app-tile:focus-visible {
	outline: 3px solid #fff;
	outline-offset: -6px;
}

@media (prefers-reduced-motion: reduce) {
	.app-shell .app-tile { transition: none; }
	.app-shell .app-tile:active { transform: none; }
}

/* Sized by HEIGHT, never width: the extracted glyphs run 0.99 to 1.26 in
   aspect, so matching widths would leave the tall ones visibly larger. */
.app-shell .app-tile-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 58px;
}

.app-shell .app-tile-icon img {
	max-height: 100%;
	max-width: 100%;
	width: auto;
	height: auto;
	display: block;
}

.app-shell .app-tile-label {
	font-size: var(--fs-label);
	font-weight: 800;
	letter-spacing: .05em;
	line-height: 1.25;
	text-transform: uppercase;
	text-wrap: balance;
}

/* Two tiles carry their own colour rather than the season's -- they mean
   "caution" and "emergency", which must not read as decoration and must not
   change with the calendar. Both kept exactly as exported.
   The foreground is dark, not white: the original art set white captions on
   these, which is 1.6:1 on the amber and 2.6:1 on the orange. brightness(0)
   turns the white line art black while preserving its alpha, so the icon
   follows the caption instead of staying white on its own. */
.app-shell .app-tile--caution { background: #ffc201; color: #3a2c00; }
.app-shell .app-tile--urgent  { background: #ff7900; color: #331500; }

.app-shell .app-tile--caution:hover,
.app-shell .app-tile--caution:focus-visible { color: #3a2c00; }
.app-shell .app-tile--urgent:hover,
.app-shell .app-tile--urgent:focus-visible  { color: #331500; }

.app-shell .app-tile--caution .app-tile-icon img,
.app-shell .app-tile--urgent .app-tile-icon img {
	filter: brightness(0);
	opacity: .82;
}

.app-shell .app-tile--caution:focus-visible,
.app-shell .app-tile--urgent:focus-visible { outline-color: #3a2c00; }


/* --------------------------------------------------------------------------
   4. Report shell -- shared by every appcontent.php getcontent type
   --------------------------------------------------------------------------
   Those pages are built as nested tables with a coloured <tr> per section
   heading. Normalising them here means Snow Report, Lift Status, Grooming
   and the rest inherit one type scale instead of each carrying its own.
   -------------------------------------------------------------------------- */

.app-shell #app-content,
.app-shell #page-content {
	font-size: var(--fs-body);
	line-height: var(--lh-body);
	color: var(--ink);
}

.app-shell #app-content h1,
.app-shell #page-content h1 {
	font-size: var(--fs-h1);
	line-height: var(--lh-heading);
	letter-spacing: var(--tracking-title);
	font-weight: 800;
	margin: 0;
}

.app-shell #app-content h2,
.app-shell #page-content h2 {
	font-size: var(--fs-h2);
	line-height: var(--lh-heading);
	letter-spacing: var(--tracking-title);
	font-weight: 800;
	margin: 0;
}

.app-shell .table-radius {
	border-radius: var(--radius);
	overflow: hidden;
}

/* Deliberately no id in this selector. An id outranks any number of classes,
   so the earlier "#app-content table th" version silently beat the trail
   report's own column-header rule -- which is far more specific in intent but
   carries no id -- and forced 16px headers no matter what the token said.
   .app-shell alone keeps this app-only while still losing to the specific
   rules that need to override it. */
.app-shell table td,
.app-shell table th {
	font-size: var(--fs-body);
	vertical-align: middle;
}


/* --------------------------------------------------------------------------
   5. Trail report (appcontent.php getTrailReport)
   -------------------------------------------------------------------------- */

.app-trail-report {
	font-size: var(--fs-body);
	line-height: var(--lh-body);
	color: var(--ink);
}

.app-trail-report p {
	margin: 0 0 .8em;
}

/* Timestamp, top right */
.app-trail-report .trail-report-stamp {
	font-size: var(--fs-small);
	color: var(--ink-muted);
}

/* Open / total counters */
.app-trail-report .rcr-element-box-title-summertrailreport {
	font-size: var(--fs-hero) !important;
	line-height: var(--lh-tight);
	font-weight: 800;
	color: var(--app-accent);
}

.app-trail-report .rcr-element-box-title-summertrailreport-title {
	font-size: var(--fs-h3);
	font-weight: 800;
	letter-spacing: var(--tracking-title);
	line-height: var(--lh-heading);
	margin-top: var(--sp-1);
}

/* Body copy: conditions, notices, chairlift hours, events */
.app-trail-report .trail-copy {
	font-size: var(--fs-body);
	line-height: var(--lh-body);
	margin-top: var(--sp-3);
	padding: 0 var(--sp-4);
}

.app-trail-report .trail-copy p {
	margin: 0 0 .8em;
}

/* One heading style for the Biking/Hiking Conditions labels, Notices,
   Chairlift Hours, Upcoming Events and the per-section trail headings. Every
   heading on the page is the same size, so the eye has a single rhythm to
   follow instead of four competing ones. */
.app-trail-report .trail-copy-label,
.app-trail-report .trail-panel-title,
.app-trail-report h3.trail-section-title {
	font-size: var(--fs-h2);
	font-weight: 800;
	letter-spacing: var(--tracking-title);
	line-height: var(--lh-heading);
	text-transform: uppercase;
	color: var(--app-accent);
	margin: 0 0 var(--sp-2);
}

/* The conditions label is a <span> inside its own paragraph, so it has to be
   promoted to its own line to sit like the other headings. */
.app-trail-report .trail-copy-label {
	display: block;
}

.app-trail-report .trail-section-head {
	margin: var(--sp-6) 0 var(--sp-2);
	padding: 0 var(--sp-1);
}

.app-trail-report h3.trail-section-title {
	margin-bottom: var(--sp-1);
}

.app-trail-report .trail-section-legend {
	font-size: var(--fs-label);
	font-weight: 900;
	letter-spacing: var(--tracking-title);
}

.app-trail-report .trail-legend-open   { color: var(--status-open); }
.app-trail-report .trail-legend-closed { color: var(--status-closed); }

/* Trail table.
   table-layout:fixed is the important part. With the default (auto) each
   section table sizes its own columns from its own content, so Elk Side,
   Timber Side and Base Area all came out different widths. Fixed takes the
   widths below and nothing else, so all three tables line up. */
.app-trail-report table.trail-report {
	font-size: var(--fs-body);
	margin-bottom: 0;
	table-layout: fixed;
	width: 100%;
}

.app-trail-report table.trail-report th,
.app-trail-report table.trail-report td {
	vertical-align: middle;
	padding: .55rem .35rem;
}

/* No white-space:nowrap. A table grows to fit its contents rather than shrink,
   so nowrap headers would set a minimum width for the whole report and push
   the page wider than the screen. */
.app-trail-report table.trail-report thead th {
	font-size: var(--fs-nano);
	font-weight: 800;
	letter-spacing: .04em;
	line-height: 1.2;
	text-transform: uppercase;
	color: var(--ink-muted);
	white-space: normal;
	word-break: break-word;
}

/* Percentages, so the four columns hold their proportions from a 320px phone
   up to a tablet. Sized off the widest thing each has to hold: the status
   column has to fit the hiker+bike sprite, which is 54px at 20px tall. */
.app-trail-report table.trail-report .trail-col-num    { width: 12%; text-align: center !important; }
.app-trail-report table.trail-report .trail-col-level  { width: 16%; text-align: center !important; }
.app-trail-report table.trail-report .trail-col-name   { width: 48%; text-align: left; }
.app-trail-report table.trail-report .trail-col-status { width: 24%; text-align: center !important; }

/* Sized by HEIGHT, never width. The trimmed sprites run 0.72 (hiker) to 2.69
   (hiker+bike) in aspect, so equal widths would render the hiker at roughly
   four times the visual weight of the combined icon. Equal heights make them
   read as one set. */
.app-trail-report table.trail-report .trail-col-level img,
.app-trail-report table.trail-report .trail-col-status img {
	height: 20px;
	width: auto;
	max-width: 100%;
	display: block;
	margin: 0 auto;
}


/* --------------------------------------------------------------------------
   6. Width containment
   --------------------------------------------------------------------------
   The legacy report markup nests a lot of horizontal padding, and the outer
   wrapper is a <table>. Tables grow to fit their contents rather than shrink,
   so any child with a large minimum width drags the whole page wider than the
   screen -- which reads as content clipped off the right edge with no way to
   scroll to it. Measured on a 360px viewport the usable column was about
   194px, against a caption the theme renders at 30px.
   -------------------------------------------------------------------------- */

/* Backstop. Nothing in the app may push the document sideways. */
.app-shell #app-content,
.app-shell #page-content {
	max-width: 100%;
	overflow-x: hidden;
}

/* px-5 is 3rem a side. On the wrapper table that is 96px of a 360px screen
   spent on nothing, before any of the nested padding below it. */
.app-shell #app-content .px-5,
.app-shell #page-content .px-5 {
	padding-left: var(--sp-3) !important;
	padding-right: var(--sp-3) !important;
}

/* Bootstrap's .row carries -15px side margins that a .container is meant to
   cancel out. Two rows in getTrailReport() -- the legend and the events block
   -- sit outside any container, so those margins leak straight off the edge. */
.app-trail-report .row {
	margin-left: 0;
	margin-right: 0;
}

.app-trail-report .container {
	max-width: 100%;
	padding-left: 0;
	padding-right: 0;
}

/* style.css:1474 sets this caption to 30px !important, which beats a plain
   token rule no matter how specific. At 30px "BIKE TRAILS OPEN" does not fit
   the column, hence the clipped word in the screenshot. */
.app-trail-report .rcr-element-box-title-summertrailreport-title {
	font-size: var(--fs-h3) !important;
}

/* Staff-entered copy must never set the floor width -- one long URL or
   unbroken word in a notice would widen the whole report. */
.app-trail-report,
.app-trail-report p,
.app-trail-report td,
.app-trail-report .trail-copy {
	overflow-wrap: break-word;
	word-wrap: break-word;
}
