/**
 * Global Weather Pro - Main Styles
 * Theme loader and base styles for the weather widget
 * 
 * Theme System:
 * - Dark Theme: gwpro-dark-theme.css
 * - Light Theme: gwpro-light-theme.css
 * - Alert Styles: alert-icon-styles.css
 */

/* ============================================= */
/* Global Reset & Base Styles                   */
/* ============================================= */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ============================================= */
/* Transition Defaults                          */
/* ============================================= */

.weather-widget-header,
.weather-widget-sidebar,
.weather-widget-header *,
.weather-widget-sidebar * {
  transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform;
  transition-duration: 200ms;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Disable transitions for reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  .weather-widget-header,
  .weather-widget-sidebar,
  .weather-widget-header *,
  .weather-widget-sidebar * {
    transition: none !important;
    animation: none !important;
  }
}

/* ============================================= */
/* Utility Classes                              */
/* ============================================= */

/* No-select utility */
.no-select {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

/* Screen reader only - Accessibility */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

/* Visually hidden but focusable */
.sr-only-focusable:focus,
.sr-only-focusable:active {
  position: static;
  width: auto;
  height: auto;
  padding: inherit;
  margin: inherit;
  overflow: visible;
  clip: auto;
  white-space: normal;
}

/* ============================================= */
/* Container Base Styles                        */
/* ============================================= */

.weather-widget-container {
  width: 100%;
  max-width: 100%;
}

#weather-widget-container-header,
#weather-widget-container-sidebar {
  width: 100%;
}

/* ============================================= */
/* Focus Styles for Accessibility               */
/* ============================================= */

/* Custom focus ring for interactive elements */
.weather-widget-header a:focus-visible,
.weather-widget-header button:focus-visible,
.weather-widget-sidebar a:focus-visible,
.weather-widget-sidebar button:focus-visible,
[data-role="unit-toggle"]:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* Remove default outline when using focus-visible */
.weather-widget-header a:focus:not(:focus-visible),
.weather-widget-header button:focus:not(:focus-visible),
.weather-widget-sidebar a:focus:not(:focus-visible),
.weather-widget-sidebar button:focus:not(:focus-visible) {
  outline: none;
}

/* ============================================= */
/* Skip Link for Accessibility                  */
/* ============================================= */

.gwpro-skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px 16px;
  z-index: 100;
  text-decoration: none;
  font-weight: 600;
}

.gwpro-skip-link:focus {
  top: 0;
}

/* ============================================= */
/* Bottom-right controls (buttons + alert)       */
/* ============================================= */

/* Make the tab wrapper a positioning context */
.weather-widget-header {
  position: relative;
}

/* ============================================= */
/* Print Styles                                 */
/* ============================================= */

@media print {
  .weather-widget-header,
  .weather-widget-sidebar {
    background: #fff !important;
    color: #000 !important;
    box-shadow: none !important;
    border: 1px solid #ccc !important;
  }

  .weather-widget-header::before,
  .weather-widget-sidebar::before {
    display: none !important;
  }

  .alert-icon-class,
  .forecast-toggle-controls {
    display: none !important;
  }
}
/* ============================================================================
   Font-Independent Layout Normalization
   ============================================================================
   The Typography setting now offers 18 fonts with very different metrics
   (x-heights, character widths, default leading). These rules pin down every
   dimension that a font could otherwise influence, so the widget layout stays
   identical no matter which font the user selects.
   ========================================================================= */

/* 1. Normalize optical size and vertical rhythm.
   - font-size-adjust scales every font so its x-height matches Roboto's
     (aspect ~0.52), so small-x-height serifs (EB Garamond, Playfair Display)
     don't render visually smaller than the sans-serifs at the same em size.
     Browsers without support simply ignore it.
   - An explicit unitless line-height overrides each font's own default
     leading, which otherwise varies enough to shift rows vertically. */
.weather-widget-header,
.weather-widget-sidebar {
  font-size-adjust: 0.52;
  line-height: 1.4;
  /* Tabular (fixed-width) numerals keep temperatures, times, and
     percentages the same width in every font, including proportional
     serifs, so columns don't jitter between values. */
  font-variant-numeric: tabular-nums lining-nums;
}

/* 2. Interactive controls never wrap or reflow in wide fonts.
   Playfair Display and Merriweather are ~15-20% wider than Roboto; without
   nowrap, tab labels like "Precipitation" or "UV Index" wrap to two lines
   and change the tab bar height. */
.weather-widget-header .tablinks,
.weather-widget-header .forecast-toggle-btn,
.weather-widget-header .unit-toggle-btn,
.weather-widget-sidebar .unit-toggle-btn {
  white-space: nowrap;
}

/* 3. Fixed-width forecast columns.
   The theme stylesheets give hourly cells only a min-width, so wide fonts
   grow individual columns and desynchronize the strip. Locking flex-basis
   and width makes column geometry font-independent. (Widget-class prefix
   deliberately out-specifies the equal-specificity theme rules, which load
   after this file.) */
.weather-widget-header #hourly-tabs .flex-tabcontent > div,
.weather-widget-header #seven-day-tabs .flex-tabcontent > div {
  flex: 0 0 5em;
  width: 5em;
  max-width: 5em;
  min-width: 5em;
  text-align: center;
}

/* 4. Truncate overflow inside fixed columns instead of breaking layout.
   Each cell stacks three block rows (label, icon, value); any row whose
   text exceeds the fixed column width ellipsizes. Full values remain
   available via existing title/aria-label attributes (e.g. AQI badges). */
.weather-widget-header .flex-tabcontent > div > div {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 5. Cap the weather location's line length so long addresses wrap early
   instead of pushing right-side elements out of position.
   30ch fits roughly 32 proportional characters per line (the width of
   "University of Florida, Southwest"), so e.g.
   "University of Florida, Southwest 40th Place, Gainesville, FL, US"
   renders as two-to-three short lines inside a fixed-width box. Because
   ch is font-relative, the cap tracks the selected font automatically:
   wide fonts get a wider box, monospace wider still, but always the same
   character count — so the elements to the right of the location sit in
   the same place no matter the font or the address length. The min()
   guard keeps the box from exceeding its container on narrow screens.
   (Widget-class prefix out-specifies the themes' max-width: 100% rules.) */
.weather-widget-header .weather-city,
.weather-widget-sidebar .weather-location {
  max-width: min(30ch, 100%);
  white-space: normal;
  overflow-wrap: break-word;
}

/* 6. Column discipline for the header's top row.
   The location column yields (shrinks) when space is tight; the two
   parameter columns are rigid and content-sized, and their label/value
   rows never wrap — so values like "0.23 mm" can't break onto a second
   line when a wide font eats the horizontal space. Any remaining box
   slack on the wrapped location heading is removed at runtime by
   gwproFitLocationWidth() in weatherApiAdapter.js, which pins the
   heading's width to its widest rendered line. */
.weather-widget-header .custom-flex-col1 {
  flex: 0 1 auto;
  min-width: 0;
}

.weather-widget-header .custom-flex-col2,
.weather-widget-header .custom-flex-col3 {
  flex: 0 0 auto;
}

.weather-widget-header .custom-flex-col2 > div,
.weather-widget-header .custom-flex-col3 > div {
  white-space: nowrap;
}

/* Neutral setup / failure message shown in place of widget content.
   Used when no location has been configured, or when weather data
   could not be loaded. Inherits the widget's own font and colours so it
   does not look like a broken element. */
.gwpro-setup-message {
    padding: 1.5em 1em;
    margin: 0;
    text-align: center;
    font-size: 0.95rem;
    line-height: 1.5;
    opacity: 0.85;
}

/* ============================================================================
   Phone Layout (<= 600px)
   ============================================================================
   The header widget was previously removed on phones by a userAgent test in
   headerWidget.js. It now renders everywhere, so this block reflows the
   desktop three-column layout into a single-column card.

   Two things made the widget unusable at phone width before:

   1. The 7-day strip has no .scroll-container (unlike the hourly strip), and
      main-styles pins every forecast column to a fixed 5em. Seven columns plus
      gaps is ~41em / 656px, which forced horizontal scrolling on the whole
      PAGE, not just the strip.
   2. .forecast-toggle-row and .alert-container are absolutely positioned
      against the article with right/bottom offsets sized for a wide card, so
      at phone width they landed on top of the forecast content.

   All selectors are prefixed with .weather-widget-header so they out-specify
   the single-class rules in gwpro-dark-theme.css / gwpro-light-theme.css,
   which are injected after this stylesheet. Nothing here applies above 600px.
   ========================================================================= */

/* The disclosure control exists in the markup at every width but is only ever
   shown on phones. */
.gwpro-mobile-expand-row {
  display: none;
}

@media (max-width: 600px) {
  /* --- Card shell ------------------------------------------------------- */

  /* Flex column so the alert notice can be pulled above the fold with order,
     independent of its position at the end of the markup. */
  .weather-widget-header {
    display: flex;
    flex-direction: column;
    padding: 0.875em;
    margin: 0.5em 0;
  }

  .weather-widget-header .flex-row1 { order: 1; }
  .weather-widget-header .alert-container { order: 2; }
  .weather-widget-header .gwpro-mobile-expand-row { order: 3; }
  .weather-widget-header #seven-day-tabs { order: 4; }
  .weather-widget-header #hourly-tabs { order: 5; }

  /* --- Current conditions ---------------------------------------------- */

  /* The 900px breakpoint turns every .flex-row into a column, which also
     stacks the icon, temperature and unit toggle. Keep that hero row
     horizontal - it is the widget's signature element. */
  .weather-widget-header .custom-row {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5em;
  }

  .weather-widget-header #current-condition-icon {
    width: 4em;
    height: 4em;
  }

  .weather-widget-header .weather-city {
    font-size: 1.25em;
  }

  /* --- Parameter columns ------------------------------------------------ */

  /* The two parameter columns (rain chance, gusts, UV, sunrise, low /
     precipitation, visibility, humidity, sunset, high) are hidden outright on
     phones rather than reflowed. Ten label/value pairs is a lot of dense text
     on a small screen, and all but two of those figures are also present in
     the forecast strips, which are the better place to read them.

     The exceptions are sunrise and sunset: there is no forecast tab for
     either, so hiding these columns removes both from the phone layout
     entirely. If they need to come back, the place for them is the summary
     card above, not a re-expanded column.

     This is unconditional at phone width - it is not tied to the collapsed
     state, so the disclosure control reveals the forecast only. */
  .weather-widget-header .custom-flex-col2,
  .weather-widget-header .custom-flex-col3 {
    display: none;
  }

  /* --- Tab strips ------------------------------------------------------- */

  /* Eight category tabs wrap into four rows at phone width. One swipeable row
     with snap points keeps the control compact and the card height stable.

     justify-content MUST be flex-start here. Both theme stylesheets set
     `.tab { justify-content: center }` inside their own max-width:900px block,
     which is harmless while the tabs wrap, but breaks a horizontal scroll
     container: centred content overflows equally in both directions, and the
     part that overflows past the container's left edge sits at a negative
     offset that scrollLeft cannot reach (it is clamped at 0). The end of the
     strip stays reachable, so the symptom is one-sided - you can swipe to the
     last tab but cannot swipe back to the first. */
  .weather-widget-header .tab {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    margin: 0.75em 0 0.5em 0;
    padding-bottom: 0.25em;
    scrollbar-width: none;
  }

  .weather-widget-header .tab::-webkit-scrollbar {
    display: none;
  }

  /* 2.75em against a 0.85em font is ~44px: the minimum comfortable touch
     target (WCAG 2.5.8 asks for 24px, platform guidance for 44px). */
  .weather-widget-header .tablinks {
    flex: 0 0 auto;
    scroll-snap-align: start;
    display: inline-flex;
    align-items: center;
    min-height: 2.75em;
    padding: 0.5em 0.9em;
    font-size: 0.85em;
  }

  /* --- Forecast strips -------------------------------------------------- */

  /* Give the 7-day strip the horizontal scroll the hourly strip already has,
     so seven fixed-width columns can no longer overflow the page. */
  .weather-widget-header #seven-day-tabs .tabcontent,
  .weather-widget-header #hourly-tabs .scroll-container {
    overflow-x: auto;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
  }

  /* 4.5em columns fit four-and-a-bit per screen at 360px, which reads as
     "there is more to swipe" rather than as a clipped column. */
  .weather-widget-header #hourly-tabs .flex-tabcontent > div,
  .weather-widget-header #seven-day-tabs .flex-tabcontent > div {
    flex: 0 0 4.5em;
    width: 4.5em;
    min-width: 4.5em;
    max-width: 4.5em;
  }

  /* Same reasoning as .tab above: a centred flex row inside a horizontal
     scroll container loses its leading items. */
  .weather-widget-header .flex-tabcontent {
    justify-content: flex-start;
    gap: 0.5em;
  }

  /* --- Controls that were absolutely positioned ------------------------- */

  .weather-widget-header .forecast-toggle-row,
  .weather-widget-header .alert-container {
    position: static;
    right: auto;
    bottom: auto;
    justify-content: flex-start;
    padding: 0;
    margin: 0.25em 0;
  }

  .weather-widget-header .forecast-toggle-btn {
    min-height: 2.5em;
  }

  /* --- Disclosure control ---------------------------------------------- */

  .weather-widget-header .gwpro-mobile-expand-row {
    display: block;
    margin: 0.75em 0 0.25em 0;
  }

  /* currentColor and transparent rather than theme variables, so the control
     inherits whichever palette (dark or light) is active without needing a
     copy in each theme stylesheet. */
  .weather-widget-header .gwpro-mobile-expand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    width: 100%;
    min-height: 2.75em;
    padding: 0.625em 1em;
    font: inherit;
    font-size: 0.875em;
    font-weight: 600;
    color: inherit;
    background: transparent;
    border: 1px solid currentColor;
    border-radius: 0.5em;
    opacity: 0.85;
    cursor: pointer;
  }

  .weather-widget-header .gwpro-mobile-expand:hover {
    opacity: 1;
  }

  .weather-widget-header .gwpro-mobile-expand-chevron {
    display: inline-block;
    transform: rotate(180deg);
    transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  /* --- Collapsed state -------------------------------------------------- */

  /* toggleSevenDayHourly() sets `display` as an inline style on these two
     regions, so the collapsed state has to out-rank an inline declaration.
     This is the one place !important is load-bearing rather than cosmetic. */
  .weather-widget-header.gwpro-mobile-collapsed #seven-day-tabs,
  .weather-widget-header.gwpro-mobile-collapsed #hourly-tabs {
    display: none !important;
  }

  .weather-widget-header.gwpro-mobile-collapsed .gwpro-mobile-expand-chevron {
    transform: rotate(0deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .weather-widget-header .gwpro-mobile-expand-chevron {
    transition: none;
  }
}
