/* SuperiorWaves. Mobile first: nearly everybody opens this on a phone at the ramp, so the
   layout is built for a thumb and only widens out on a desktop. */

html, body {
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  margin: 0;
  -webkit-text-size-adjust: 100%;
}

/* Respect the notch and the home indicator on phones. */
.sw-safe-bottom {
  padding-bottom: env(safe-area-inset-bottom, 0);
}

h1:focus {
  outline: none;
}

/* ------------------------------------------------------------------ verdict colours

   One palette used everywhere a go / no-go call appears, so a colour always means the same
   thing whether it is on the hero, a post card or the hourly strip. */

.sw-verdict-excellent { --sw-verdict: #14b8a6; }
.sw-verdict-good      { --sw-verdict: #4ade80; }
.sw-verdict-marginal  { --sw-verdict: #fbbf24; }
.sw-verdict-poor      { --sw-verdict: #fb923c; }
.sw-verdict-dangerous { --sw-verdict: #ef4444; }

.sw-verdict-bar {
  background: var(--sw-verdict, #90a4ae);
  border-radius: 4px;
  height: 100%;
  width: 6px;
}

.sw-verdict-text {
  color: var(--sw-verdict, #90a4ae);
  font-weight: 700;
}

/* ------------------------------------------------------------------ hero */

.sw-hero {
  background: linear-gradient(150deg, #0b2942 0%, #123a5c 45%, #1b5478 100%);

  /* Rounded all round, because the page has side padding and the hero sits inside it as a
     card. Square top corners only made sense back when it bled to the window edge. */
  border-radius: 20px;
  color: #fff;
  overflow: hidden;
  position: relative;
}

.sw-hero::after {
  background: radial-gradient(circle at 80% 10%, rgba(255, 255, 255, 0.14), transparent 55%);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
}

.sw-hero-call {
  font-size: clamp(2.6rem, 13vw, 4.2rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1;
}

.sw-hero-sub {
  font-size: 1.05rem;
  font-weight: 500;
  opacity: 0.92;
}

.sw-score-ring {
  align-items: center;
  display: flex;
  justify-content: center;
  position: relative;
}

.sw-score-ring-value {
  font-size: 1.5rem;
  font-weight: 800;
  position: absolute;
}

/* ------------------------------------------------------------------ hourly strip */

.sw-hour-strip {
  -webkit-overflow-scrolling: touch;
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 2px 12px 2px;
  scroll-snap-type: x proximity;
}

.sw-hour-strip::-webkit-scrollbar {
  height: 6px;
}

.sw-hour-strip::-webkit-scrollbar-thumb {
  background: rgba(128, 128, 128, 0.35);
  border-radius: 3px;
}

.sw-hour {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  border-radius: 12px;
  flex: 0 0 auto;
  min-width: 96px;
  padding: 12px 10px;
  scroll-snap-align: start;
  text-align: center;
  transition: transform 120ms ease;
}

.sw-hour > span { display: block; white-space: nowrap; }
.sw-hour-time { font-size: .75rem; font-weight: 700; opacity: .8; }
.sw-hour-waves { font-size: .9rem; font-weight: 800; line-height: 1.2; }
.sw-hour-detail { font-size: .7rem; line-height: 1.4; opacity: .8; }

.sw-hour-selected {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: 1px;
}

.sw-hour-night {
  opacity: 0.55;
}

.sw-hour-bar {
  background: var(--sw-verdict, #90a4ae);
  border-radius: 3px;
  height: 5px;
  margin: 6px auto 0 auto;
  width: 70%;
}

/* ------------------------------------------------------------------ wave scale */

.sw-wave-track {
  background: linear-gradient(90deg, #14b8a6 0%, #4ade80 22%, #fbbf24 48%, #fb923c 70%, #ef4444 100%);
  border-radius: 6px;
  height: 10px;
  position: relative;
  width: 100%;
}

.sw-wave-marker {
  background: #fff;
  border: 3px solid #0b2942;
  border-radius: 50%;
  height: 20px;
  margin-left: -10px;
  position: absolute;
  top: -5px;
  width: 20px;
}

/* ------------------------------------------------------------------ maps and editor */

.sw-map {
  border-radius: 14px;
  height: 320px;
  overflow: hidden;
  width: 100%;
  z-index: 0;
}

.sw-map-small {
  height: 200px;
}

/* Leaflet stacks above MudBlazor overlays without this. */
.leaflet-pane,
.leaflet-top,
.leaflet-bottom {
  z-index: 400 !important;
}

.sw-editor {
  min-height: 180px;
}

.ql-toolbar.ql-snow,
.ql-container.ql-snow {
  border-color: var(--mud-palette-lines-default);
}

.ql-toolbar.ql-snow {
  border-radius: 8px 8px 0 0;
}

.ql-container.ql-snow {
  border-radius: 0 0 8px 8px;
  font-family: inherit;
  font-size: 1rem;
}

.ql-editor {
  min-height: 170px;
}

/* ------------------------------------------------------------------ post content */

.sw-post-body {
  line-height: 1.65;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.sw-post-body p {
  margin: 0 0 0.85em 0;
}

.sw-post-body ul,
.sw-post-body ol {
  margin: 0 0 0.85em 0;
  padding-left: 1.4em;
}

.sw-post-body blockquote {
  border-left: 3px solid var(--mud-palette-primary);
  color: var(--mud-palette-text-secondary);
  margin: 0 0 0.85em 0;
  padding-left: 1em;
}

.sw-post-body img {
  border-radius: 10px;
  max-width: 100%;
}

.sw-post-body a {
  color: var(--mud-palette-primary);
}

/* A magic link from an SMS lands directly on one reply, so flag which one. */
.sw-flash {
  animation: sw-flash-anim 2.4s ease-out;
}

@keyframes sw-flash-anim {
  0%   { background-color: rgba(251, 191, 36, 0.35); }
  100% { background-color: transparent; }
}

/* ------------------------------------------------------------------ layout helpers */

.sw-page {
  margin: 0 auto;
  max-width: 900px;

  /* MudMainContent already clears the fixed app bar. This is just breathing room under it.
     Never add a pt-* utility class to MudMainContent itself: those carry !important and will
     wipe out that clearance, dropping the page behind the bar. */
  padding-top: 12px;
  padding-bottom: 84px;
}

.sw-wide {
  max-width: 1180px;
}

.sw-sticky-actions {
  backdrop-filter: blur(8px);
  bottom: 0;
  position: sticky;
  z-index: 5;
}

.sw-truncate-2 {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  display: -webkit-box;
  overflow: hidden;
}

.sw-truncate-3 {
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  display: -webkit-box;
  overflow: hidden;
}

.sw-clickable {
  cursor: pointer;
}

.sw-clickable:hover {
  filter: brightness(1.03);
}

/* ------------------------------------------------------------------ first visit tour

   The illustrations are inline SVG sized by their own viewBox, so the only thing needed here is
   a box that does not change height as the reader steps between them. Without a fixed aspect the
   dialog grows and shrinks under the buttons and they move out from under a thumb mid-tap. */

/* An edge on the tour, so it reads as a thing sitting on top of the page rather than as part of
   it. In dark mode the dialog surface and the dimmed page behind it are close enough in tone that
   without this the panel has no discernible edge at all. Both selectors are here because whether
   the class lands on the .mud-dialog element itself depends on how the dialog was opened. */

.sw-welcome-dialog,
.mud-dialog.sw-welcome-dialog {
  border: 2px solid var(--mud-palette-secondary);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
}

.sw-welcome-art {
  aspect-ratio: 480 / 210;
  width: 100%;
}

.sw-welcome-art svg {
  display: block;
  height: 100%;
  width: 100%;
}

.sw-welcome-dot {
  background: var(--mud-palette-lines-default);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  height: 9px;
  padding: 0;
  transition: background-color 140ms ease, width 140ms ease;
  width: 9px;
}

.sw-welcome-dot-on {
  background: var(--mud-palette-primary);
  border-radius: 5px;
  width: 22px;
}

.sw-welcome-dot:focus-visible {
  outline: 2px solid var(--mud-palette-primary);
  outline-offset: 2px;
}

/* ------------------------------------------------------------------ footer

   Deliberately quiet. It is where the privacy policy and terms live, which have to be reachable
   from everywhere without competing with the verdict the page is actually there to deliver. */

.sw-footer {
  padding-bottom: 8px;
}

.sw-footer-link {
  opacity: 0.72;
  white-space: nowrap;
}

.sw-footer-link:hover,
.sw-footer-link:focus-visible {
  opacity: 1;
}

/* Bottom navigation only exists on phones; desktop uses the rail in the app bar. */
.sw-bottom-nav {
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--mud-palette-lines-default);
  bottom: 0;
  left: 0;
  position: fixed;
  right: 0;
  z-index: 1200;
}

@media (min-width: 1280px) {

  .sw-bottom-nav {
    display: none;
  }

  .sw-page {
    padding-bottom: 24px;
  }
}

/* ------------------------------------------------------------------ error banner */

#blazor-error-ui {
  background: #b32121;
  bottom: 0;
  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
  box-sizing: border-box;
  color: #fff;
  display: none;
  left: 0;
  padding: 0.7rem 1.25rem;
  position: fixed;
  width: 100%;
  z-index: 3000;
}

#blazor-error-ui a {
  color: #fff;
  text-decoration: underline;
}

#blazor-error-ui .dismiss {
  cursor: pointer;
  position: absolute;
  right: 0.9rem;
  top: 0.6rem;
}

.blazor-error-boundary {
  background: #b32121;
  color: #fff;
  padding: 1rem;
}

.blazor-error-boundary::after {
  content: "Something went wrong rendering this section.";
}

/* Your own position on the map. A quiet pulse so it never gets lost among the spot pins. */
.sw-you-marker {
  animation: sw-pulse 2.4s ease-in-out infinite;
}

@keyframes sw-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

.sw-map-home {
  border-radius: 14px;
  height: 240px;
  overflow: hidden;
  width: 100%;
  z-index: 0;
}

/* The friendly "what to expect" block. Deliberately looks different from the analysis. */
.sw-expect {
  background: linear-gradient(135deg, rgba(27, 84, 120, 0.10), rgba(20, 184, 166, 0.10));
  border-left: 3px solid var(--mud-palette-secondary);
  border-radius: 10px;
  line-height: 1.7;
}

/* Present to a screen reader and to a crawler, absent to the eye. The conditions page leads
   with a verdict ring rather than a headline, so its real heading lives here. */
.sw-visually-hidden {
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

/* Clear forecast hierarchy and discoverable controls. */
.sw-page-heading, .sw-section-heading { display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; margin-bottom:20px; }
.sw-page-heading h1 { font-size:clamp(1.8rem, 5vw, 2.5rem); font-weight:800; letter-spacing:-.035em; margin:4px 0; }
.sw-page-heading p, .sw-muted { color:var(--mud-palette-text-secondary); line-height:1.6; }
.sw-eyebrow { font-size:.7rem; font-weight:800; letter-spacing:.1em; opacity:.8; }
.sw-section-nav, .sw-action-row { display:flex; gap:10px; flex-wrap:wrap; }
.sw-section-nav { margin:20px 0; }
.sw-section-nav a { color:var(--mud-palette-text-primary); border:1px solid var(--mud-palette-lines-default); border-radius:24px; padding:10px 16px; font-size:.85rem; font-weight:600; }
.sw-section-nav a:hover { background:var(--mud-palette-action-default-hover); }
.sw-dashboard-grid { display:grid; grid-template-columns:minmax(0, 1.15fr) minmax(0, 1fr); gap:18px; }
.sw-current-card h2 { font-size:clamp(1.7rem, 4vw, 2.3rem); line-height:1.2; font-weight:800; margin:12px 0 8px; }
.sw-condition-metrics { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px 16px; margin:28px 0; }
.sw-rating-note { padding-top:16px; border-top:1px solid #ffffff40; font-size:.85rem; line-height:1.6; }
.sw-comfort-card h2, .sw-section h2 { font-size:1.25rem; font-weight:800; margin:6px 0 12px; }
.sw-comfort-card p { line-height:1.65; margin:12px 0; }
.sw-section { margin-top:28px; scroll-margin-top:76px; }
#current { scroll-margin-top:76px; }
.sw-section-heading { margin-bottom:10px; }
.sw-window-summary { display:flex; gap:12px; padding:16px; margin-bottom:20px; border-left:4px solid var(--mud-palette-primary); background:var(--mud-palette-background); border-radius:8px; }
.sw-window-summary p { margin-top:5px; line-height:1.6; }
.sw-details { margin:16px 0; border-top:1px solid var(--mud-palette-lines-default); padding-top:14px; }
.sw-details summary { cursor:pointer; font-weight:700; padding:8px 0; }
.sw-details p { line-height:1.7; margin:12px 0; }
.sw-location-controls { display:grid; grid-template-columns:minmax(0, 1.5fr) minmax(0,1fr); gap:16px; }
.sw-location-controls .mud-button-root { min-height:44px; }
.sw-control-label { display:block; font-size:.75rem; font-weight:700; margin-bottom:6px; }
.sw-location-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
.sw-hour { cursor:pointer; border:1px solid var(--mud-palette-lines-default); color:var(--mud-palette-text-primary); background:var(--mud-palette-surface); font:inherit; }
.sw-hour:focus-visible, .sw-details summary:focus-visible, .sw-section-nav a:focus-visible { outline:3px solid var(--mud-palette-primary); outline-offset:3px; }
@media (max-width:700px) {
  .sw-dashboard-grid { grid-template-columns:minmax(0,1fr); }
  .sw-location-controls { grid-template-columns:minmax(0,1fr); gap:12px; }
  .sw-page-heading { margin-top:8px; }
  .sw-section-nav { gap:6px; }
  .sw-section-nav a { padding:9px 12px; font-size:.8rem; }
}
.sw-utility-nav { display:flex; justify-content:center; flex-wrap:wrap; gap:4px 12px; padding:8px 12px; border-bottom:1px solid var(--mud-palette-lines-default); }
