{"id":2139,"date":"2026-05-07T16:08:27","date_gmt":"2026-05-07T23:08:27","guid":{"rendered":"https:\/\/snow.ucsb.edu\/?page_id=2139"},"modified":"2026-05-13T13:13:41","modified_gmt":"2026-05-13T20:13:41","slug":"current-conditions","status":"publish","type":"page","link":"https:\/\/snow.ucsb.edu\/","title":{"rendered":"Current Conditions"},"content":{"rendered":"\n<style>\n  .youtube-container {\n    position: relative;\n    width: 100%;\n    max-width: 900px;\n    margin: 0 auto;\n    aspect-ratio: 16 \/ 9;\n    overflow: hidden;\n  }\n  \n  .youtube-container iframe {\n    position: absolute;\n    inset: 0;\n    width: 100%;\n    height: 100%;\n    border: 0;\n    \/* padding-bottom: 1em; *\/\n  }\n  <\/style>\n \n \n <!DOCTYPE html>\n  <html lang=\"en\">\n    \n  <!-- <div class=\"youtube-container\">\n    <iframe\n      src=\"https:\/\/www.youtube.com\/embed\/live_stream?channel=UCZvyw5JQrFFGj76Ds_VggGg&amp;autoplay=1&mute=1&playsinline=1\"\n      title=\"CUES Livestream\"\n      frameborder=\"0\" \n      allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n      allowfullscreen>\n    <\/iframe>\n  <\/div>\n  \n  <br> -->\n  \n  \n  <head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Current Conditions \u2014 Jeff Dozier Snow Study Site<\/title>\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Mono:wght@400;500&#038;family=Outfit:wght@300;400;500;600&#038;display=swap\" rel=\"stylesheet\">\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Google+Sans+Code:ital,wght,MONO@0,300..800,1;1,300..800,1&#038;display=swap\" rel=\"stylesheet\">\n  <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/4.7.0\/css\/font-awesome.min.css\">\n  <style>\n    \/* \u2500\u2500\u2500 CONFIGURATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n       Replace these with your actual proxy URL and query parameters.\n       The proxy is called once per sensor group, each returning a CSV.\n    \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  \n    \/* See CONFIG object in <script> below *\/\n  \n    :root {\n      --snow-blue:    #1a6fa8;\n      --snow-light:   #e8f4fd;\n      --snow-mid:     #205b85;\n      \/* --snow-mid:     #5ba3d0; *\/\n      --ice:          #cce8f4;\n      --night:        #0d1b2a;\n      --night-2:      #132333;\n      --night-3:      #1c3048;\n      --text-primary: #f0f6fc;\n      --text-muted:   #7eabc7;\n      --text-dim:     #639996;\n      \/* --text-dim:     #5d9d8d;  *\/\n      \/* --text-dim:     #37917b; *\/\n      \/* --text-dim:     #4a7a9b; *\/\n      --accent-green: #2ecc71;\n      --accent-amber: #f0a500;\n      --accent-red:   #e84545;\n      --border:       rgba(91,163,208,0.18);\n      --card-bg:      rgba(28,48,72,0.7);\n      --mono:         'Google Sans Code', 'DM Mono', monospace;\n      --sans:         'Outfit', sans-serif;\n    }\n  \n    \/* Adding this to try to override wordpress settings... *\/\n    .widget-root,\n    .widget-root * {\n      box-sizing: border-box;\n    }\n  \n    .widget-root {\n      font-family: var(--sans);\n      line-height: 1.4;\n    }\n  \n    .widget-root p,\n    .widget-root h1,\n    .widget-root div,\n    .widget-root span,\n    .widget-root button {\n      margin-top: 0;\n      margin-bottom: 0;\n    }\n  \n    .widget-root button {\n      font: inherit;\n    }\n  \n  \n    * { box-sizing: border-box; margin: 0; padding: 0; }\n  \n    body {\n      font-family: var(--sans);\n    }\n  \n    body .site {\n      width: 1200px;\n    }\n  \n    \/* body .site-content {\n      width: 100%;\n    } *\/\n  \n    \/* .widget-root { position: relative; z-index: 1; max-width: 860px; margin: 0 auto; } *\/\n    .widget-root {\n       position: relative; \n       z-index: 1; \n       \/* width: 98%;  *\/\n       font-size: 16px !important;\n       margin: 0 auto; \n       background: var(--night);\n       color: var(--text-primary);\n       padding: 2em 1.5em 2em; \n       border-radius: 0.75em;\n       overflow: hidden;\n    }\n  \n    \/* Subtle grid background *\/\n    .widget-root::before {\n      content: '';\n      position: absolute;\n      inset: 0;\n      background-image:\n        linear-gradient(rgba(91,163,208,0.04) 1px, transparent 1px),\n        linear-gradient(90deg, rgba(91,163,208,0.04) 1px, transparent 1px);\n      background-size: 2.5em 2.5em;\n      pointer-events: none;\n      z-index: 0;\n    }\n  \n    .widget-root > * {\n      position: relative;\n      z-index: 1;\n    }\n  \n  \n     \/* site-title: Actual website title *\/\n    \/* In widget preview, this is actually the widget title. *\/\n    .widget-site-title {\n      font-size: 0.85em;  \n      font-weight: 550;\n      letter-spacing: 0.14em;\n      text-transform: uppercase;\n      color: var(--text-muted);\n      margin-top: 0.0em;\n      margin-bottom: 0.25em;\n    }\n  \n    \/* \u2500\u2500 Header \u2500\u2500 *\/\n    \/* -- includes current conditions title, pill .. *\/\n    .widget-header {\n      display: flex;\n      align-items: flex-start;\n      justify-content: space-between;\n      margin-top : 0.0em;\n      margin-bottom: 2em;\n      gap: 1em;\n      flex-wrap: wrap;\n      padding-bottom: 0.25em;\n    }  \n  \n    .widget-title {\n      font-size: 1.35em;\n      font-weight: 300;\n      color: var(--text-primary);\n      letter-spacing: -0.0em;\n      \/* text-transform: none; *\/\n    }\n    .widget-title strong { font-weight: 600; color: #fff; }\n  \n  \n    \/* Data status: *\/\n    .status-pill {\n      display: flex;\n      align-items: center;\n      gap: 0.5em;\n      background: var(--card-bg);\n      border: 0.03em solid var(--border);\n      border-radius: 999px;\n      padding: 0.4em 0.8em;\n      font-size: 0.75em;\n      color: var(--text-muted);\n      white-space: nowrap;\n    }\n    .status-dot {\n      width: 0.5em; height: 0.5em;\n      border-radius: 50%;\n      background: var(--accent-green);\n      box-shadow: 0 0 0.4em var(--accent-green);\n      flex-shrink: 0;\n    }\n    .status-dot.loading { background: var(--accent-amber); box-shadow: 0 0 0.4em var(--accent-amber); animation: pulse 1.2s infinite; }\n    .status-dot.error   { background: var(--accent-red);   box-shadow: 0 0 0.4em var(--accent-red); }\n    @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }\n  \n  \n    \/* \u2500\u2500 Error banner \u2500\u2500 *\/\n    .error-banner {\n      display: none;\n      background: rgba(232,69,69,0.1);\n      border: 0.031em solid rgba(232,69,69,0.3);\n      border-radius: 0.5em;\n      padding: 0.5em 0.875em;\n      font-size: 0.81em;\n      color: #f0a0a0;\n      margin-bottom: 1em;\n    }\n  \n    \/* ------------------------------------------------------------------------------------------------------------------------------ *\/\n    \/* \u2500\u2500 Section labels \u2500\u2500 *\/\n    .widget-section-label {\n      font-family: var(--mono);\n      font-size: 0.85em;\n      letter-spacing: 0.12em;\n      text-transform: uppercase;\n      color: var(--ice);\n      \/* margin: 1.75em 0 0.75em; *\/\n      display: flex;\n      align-items: center;\n      gap: 0.625em;\n      \n      \/* Additional fields for adding buttons *\/\n      flex: 1; \/* allows the divider line to stretch *\/\n      padding-left: 0em;\n      padding-right: 1em; \n      padding-top: 0em;\n      padding-bottom: 0em;\n    }\n    \n    \/* Horiz. Line *\/\n    .widget-section-label::after {\n      content: '';\n      flex: 1;\n      align-items: center;\n      height: 0.1em;\n      background: var(--border);\n    }\n  \n    \/* Full section heading, including line and button *\/\n    .widget-section-head {\n      display: flex;\n      align-items: center;     \/* aligns button with heading text *\/\n      justify-content: space-between; \/* heading left, button right *\/\n      width: 100%;\n      padding-top: 1.2em;\n      padding-bottom: 0.5em;\n    } \n  \n    \/* should rename to unit toggle... *\/\n    .widget-section-toggle {\n      margin-left: auto;\n      display: flex;\n      align-items: center;\n      background: var(--card-bg);\n      border: 0.031em solid var(--border);\n      border-radius: 999px;   \/* border for full unit bar *\/\n      font-size: 0.7em;    \/* unit button font size controlled here... *\/\n      font-weight: 500;\n      \/* padding: 0.0em;  *\/\n      \/* gap: 2px;  *\/\n    }\n  \n    \n  \n    \/* \u2500\u2500 Unit button toggle\u2500\u2500 *\/\n    \/* .unit-toggle {\n      display: flex;\n      align-items: center;\n      background: var(--card-bg);\n      border: 0.031em solid var(--border);\n      border-radius: 999px;\n      padding: 0.19em;\n      gap: 0.125em;\n    } *\/\n  \n    .unit-btn {\n      letter-spacing: 0.06em;  \/* letter spacing controlled here..*\/\n      padding: 0.25em 0.75em;  \/* padding for individual button controlled here..*\/\n      border-radius: 999px;    \/* border for individual unit button *\/\n      border: none;\n      cursor: pointer;\n      background: transparent;\n      color: var(--text-dim);\n      transition: background 0.15s, color 0.15s;\n    }\n    .unit-btn.active {\n      background: var(--snow-mid);\n      color: #fff;\n    }\n  \n    .unit-btn:hover:not(.active) { color: var(--text-muted); }\n  \n  \n  \n  \n    \/* ------------------------------------------------------------------------------------------------------------------------------ *\/\n   \n    \/* \u2500\u2500 Metric cards \u2500\u2500 *\/\n    .metric-grid {\n      display: grid;\n      grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));\n      gap: 0.6em;\n    }\n  \n  \n    .metric-card {\n      background: var(--card-bg);\n      border: 0.03em solid var(--border);\n      border-radius: 0.625em;\n      backdrop-filter: blur(0.5em);\n      transition: border-color 0.2s;\n      min-height: 6.6em;\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      padding: 0.5em 0.5em;\n    }\n  \n    .metric-card:hover { border-color: rgba(91,163,208,0.4); }\n  \n    \/* Measurement title *\/\n    .metric-label {\n      font-family: var(--mono);\n      font-size: 0.75em;\n      font-weight: 300;\n      \/* color: var(--text-dim); *\/\n      color: var(--ice); \n      letter-spacing: 0.06em;\n      padding-bottom: 1.0em;\n      text-transform: uppercase;\n      text-align: center;\n    }\n  \n    \/* Measurement value *\/\n    .metric-value {\n      font-size: 1.5em;\n      font-weight: 300;\n      color: #fff;\n      line-height: 1;\n      \/* letter-spacing: -0.03em; *\/\n      text-align: center;\n      \/* margin-top: 0.0em; *\/\n      \/* margin-bottom: 4.0em;  *\/\n    }\n    .metric-value .unit {\n      font-size: 1.0em;\n      font-weight: 300;\n      color: var(--text-muted);\n      margin-left: 0.5em;\n      letter-spacing: 0;\n      text-align: center;\n    }\n  \n    \/* Text on the bottom of the measurement cards *\/\n    .metric-sub {\n      font-size: 0.75em;\n      color: var(--text-dim);\n      padding-top: 1.0em;\n      padding-bottom: 0.0em;\n      \/* margin-top: 0.625em; *\/\n      \/* margin-bottom: 0px; *\/\n      text-align: center;\n    }\n  \n    \/* Confused if the settings above even matter if this is what is called? *\/\n    .metric-value.loading-val { color: var(--text-dim); font-size: 1.2em; }\n  \n  \n    \/* Wind speed and direction *\/\n    .metric-row {\n      display: flex;\n      align-items: center;\n      justify-content: center; \/*centers horizontally *\/\n      gap: 1.5em; \/*space between items *\/\n      \/* width: 100%; *\/\n    }\n  \n    \/* | for wind speed\/direction *\/\n    .divider {\n      width: 0.05em;\n      height: 1.5em;\n      background: currentColor;\n      align-self: center;\n      opacity: 0.4;\n    }\n  \n  \n    \/* Control width of wind speed and units *\/\n    .wind-speed-wrap {\n      display: flex;\n      align-items: center;\n      justify-content: flex-end;\n      \/* justify-content: flex-start; *\/\n      width: 5em; \/* fixed width *\/\n      flex-shrink: 0;\n    }\n  \n    .wind-value {\n      min-width: 3.5em; \/*reserves space for numbers *\/\n      text-align: center;\n      font-size: 1.5em;\n      font-weight: 300;\n      color: #fff;\n      line-height: 1;\n      letter-spacing: -0.03em;\n    }\n  \n    .wind-speed-wrap .unit {\n      width: 2.0em;    \/* fixed unit width *\/\n      text-align: right;\n      font-size: 1.0em;\n      font-weight: 300;\n      color: var(--text-muted);\n      margin-left: 0.5em;\n      letter-spacing: 0;\n    } \n  \n    \/* Need separate for wind val and units?? *\/\n    .wind-value.loading-val { color: var(--text-dim); font-size: 1.2em; }\n  \n  \n    \/* ----------------------------------------------------------- *\/\n    \/* \u2500\u2500 Gauge cards (i.e., percent of median cards) \u2500\u2500 *\/\n    .gauge-grid {\n      display: grid;\n      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n      gap: 0.625em;\n    }\n    .gauge-card {\n      background: var(--card-bg);\n      border: 0.031em solid var(--border);\n      border-radius: 0.625em;\n      padding: 14px 1em;\n      backdrop-filter: blur(8px);\n    }\n    .gauge-label {\n      font-family: var(--mono);\n      font-size: 0.625em;\n      color: var(--text-dim);\n      letter-spacing: 0.06em;\n      text-transform: uppercase;\n      margin-bottom: 0.625em;\n    }\n    .gauge-track {\n      height: 0.31em;\n      background: rgba(255,255,255,0.07);\n      border-radius: 0.19em;\n      overflow: hidden;\n      margin-bottom: 0.5em;\n    }\n    .gauge-fill {\n      height: 100%;\n      border-radius: 0.19em;\n      transition: width 0.8s cubic-bezier(0.4,0,0.2,1);\n      width: 0%;\n    }\n    .gauge-row { display: flex; justify-content: space-between; align-items: baseline; }\n    .gauge-pct { font-size: 1.5em; font-weight: 300; color: #fff; letter-spacing: -0.03em; }\n    .gauge-of  { font-size: 0.69em; color: var(--text-dim); }\n  \n  \n    \/* ----------------------------------------------------------- *\/\n  \n    \n    \/* For page-wide unit and status buttons *\/\n    \/* .header-controls {\n      display: flex;\n      align-items: center;\n      gap: 0.625em;\n      flex-wrap: wrap;\n      justify-content: flex-end;\n    } *\/\n  \n    \n    \/* \u2500\u2500 Footer \u2500\u2500 *\/\n    .widget-footer {\n      padding-top: 2em;\n      font-family: var(--mono);\n      font-size: 0.69em;\n      color: var(--text-dim);\n      display: flex;\n      justify-content: space-between;\n      flex-wrap: wrap;\n      gap: 0.375em;\n    }\n    .widget-footer a { color: var(--text-dim); text-decoration: none; }\n    .widget-footer a:hover { color: var(--text-muted); }\n  \n  \n    .large-icon {\n      font-size: 2.5em;\n      vertical-align: middle; \n    }\n  \n  <\/style>\n  <\/head>\n  \n\n  \n\n  <body>\n  <div class=\"widget-root\">\n  \n    <!-- Header -->\n    <div class=\"widget-header\">\n      <div>\n        <p class=\"widget-site-title\">Jeff Dozier Snow Study Site \u00b7 9,633 ft <span style=\"padding: 4px\">|<\/span> Mammoth Mountain, CA <\/p>\n        <h1 class=\"widget-title\">Current <strong>Conditions<\/strong><\/h1>\n      <\/div>\n      <div class=\"header-controls\">\n        <!-- <div class=\"unit-toggle\" role=\"group\" aria-label=\"Unit system\">  --- SITE WIDE UNIT BUTTON \n          <button class=\"unit-btn active\" id=\"btn-us\"     onclick=\"setUnitSystem('us')\">US<\/button>\n          <button class=\"unit-btn\"        id=\"btn-metric\"  onclick=\"setUnitSystem('metric')\">Metric<\/button>\n        <\/div> -->\n        <div class=\"status-pill\">\n          <div class=\"status-dot loading\" id=\"status-dot\"><\/div>\n          <span id=\"status-text\">Fetching data\u2026<\/span>\n        <\/div>\n      <\/div>\n    <\/div>\n  \n    <!-- Error banner -->\n    <div class=\"error-banner\" id=\"error-banner\"><\/div>\n  \n    <br>\n    \n    <!-- Youtube livestream -->\n    <div class=\"youtube-container\">\n      <iframe\n        src=\"https:\/\/www.youtube.com\/embed\/live_stream?channel=UCZvyw5JQrFFGj76Ds_VggGg&amp;autoplay=1&#038;mute=1&#038;playsinline=1\"\n        title=\"CUES Livestream\"\n        frameborder=\"0\" \n        allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n        allowfullscreen>\n      <\/iframe>\n    <\/div>\n    \n    <br>\n\n\n\n    <!--------------------------------------------------------------------------------------------------->\n    <!-- Snowpack header -->\n    <div class=\"widget-section-head\">\n      <p class=\"widget-section-label\"><span class=\"large-icon\">&#10053;<\/span>Snowpack<\/p> \n      <div class=\"widget-section-toggle\">\n        <button class=\"unit-btn active\" id=\"btn-snow-cm\" onclick=\"setSnowUnit('cm')\">cm<\/button>\n        <button class=\"unit-btn\" id=\"btn-snow-in\" onclick=\"setSnowUnit('in')\">in<\/button>\n      <\/div>\n    <\/div>\n    <div class=\"metric-grid\">\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Snow Depth<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-depth-south\">\u2014<span class=\"unit\" id=\"v-depth-south-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">South Side <span style=\"padding: 4px\">\u00b7<\/span> SNOdar<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">24-Hour Snow Depth Change<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-depth-south-change\">\u2014<span class=\"unit\" id=\"v-depth-south-change-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">South Side <span style=\"padding: 4px\">\u00b7<\/span> SNOdar <\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Snow Water Equivalent<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-swe-dwr\">\u2014<span class=\"unit\" id=\"v-swe-dwr-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">South Side <span style=\"padding: 4px\">\u00b7<\/span> DWR Snow Pillow <\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">24-Hour SWE Change<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-swe-dwr-change\">\u2014<span class=\"unit\" id=\"v-swe-dwr-change-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">South Side <span style=\"padding: 4px\">\u00b7<\/span> DWR Snow Pillow <\/p>\n      <\/div>\n    <\/div>\n  <\/br>\n    <div class=\"metric-grid\">\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Snow Depth<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-depth-north\">\u2014<span class=\"unit\" id=\"v-depth-north-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">North Side <span style=\"padding: 4px\">\u00b7<\/span> Lufft SHM31<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">24-Hour Snow Depth Change<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-depth-north-change\">\u2014<span class=\"unit\" id=\"v-depth-north-change-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">North Side <span style=\"padding: 4px\">\u00b7<\/span> Lufft SHM31<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Snow Water Equivalent<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-swe-ssg\">\u2014<span class=\"unit\" id=\"v-swe-ssg-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">North Side <span style=\"padding: 4px\">\u00b7<\/span> SSG Snow Pillow <\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">24-Hour SWE Change<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-swe-ssg-change\">\u2014<span class=\"unit\" id=\"v-swe-ssg-change-unit\">cm<\/span><\/p>\n        <p class=\"metric-sub\">North Side <span style=\"padding: 4px\">\u00b7<\/span> SSG Snow Pillow<\/p>\n      <\/div>\n    <\/div>\n  \n  \n    <!--------------------------------------------------------------------------------------------------->\n    <!-- Atmosphere header --> \n  \n    <div class=\"widget-section-head\">\n      <p class=\"widget-section-label\"><span class=\"large-icon\"><i class=\"fa fa-thermometer-half\"\"><\/i><\/span>ATMOSPHERE<\/p>\n      <div class=\"widget-section-toggle\">\n        <button class=\"unit-btn active\" id=\"btn-atmos-metric\" onclick=\"setAtmosPreset('metric')\">\u00b0C&thinsp;|&thinsp;m\/s<\/button>       \n        <button class=\"unit-btn\" id=\"btn-atmos-us-kt\" onclick=\"setAtmosPreset('kt')\">\u00b0F&thinsp;|&thinsp;kt<\/button>   \n        <button class=\"unit-btn\" id=\"btn-atmos-us-mph\" onclick=\"setAtmosPreset('mph')\">\u00b0F&thinsp;|&thinsp;mph<\/button>       \n      <\/div>\n    <\/div>\n    \n    <div class=\"metric-grid\">\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Air Temperature<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-airtemp\">\u2014<span class=\"unit\" id=\"v-airtemp-unit\">\u00b0C<\/span><\/p> \n        <p class=\"metric-sub\">Platform <span style=\"padding: 4px\">\u00b7<\/span> Temperature&thinsp;\/&thinsp;RH Sensor<\/p>\n      <\/div>\n  \n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Relative Humidity<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-relhum\">\u2014<span class=\"unit\">%<\/span><\/p>\n        <p class=\"metric-sub\">Platform <span style=\"padding: 4px\">\u00b7<\/span> Temperature&thinsp;\/&thinsp;RH Sensor<\/p>    \n      <\/div>\n      \n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Wind Speed & Direction<\/p>\n        <div class=\"metric-row\">\n          <p class=\"metric-value loading-val\" id=\"v-winddir\"><\/p>\n          <!-- <span class=\"divider\"><\/span> -->\n        \n          <div class=\"wind-speed-wrap\">\n            <p class=\"wind-value loading-val\" id=\"v-wind\">\u2014<span class=\"unit\" id=\"v-wind-unit\">m\/s<\/span><\/p>\n            <\/div>\n  \n        <\/div>\n        <p class=\"metric-sub\">Platform <span style=\"padding: 4px\">\u00b7<\/span> Vane Anemometer<\/p> \n      <\/div>\n  \n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Air Pressure<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-pressure\">\u2014<span class=\"unit\">mb<\/span><\/p>\n        <p class=\"metric-sub\">Instrument Bunker <span style=\"padding: 4px\">\u00b7<\/span> Barometer<\/p>\n      <\/div>\n    <\/div>\n  \n    <!--------------------------------------------------------------------------------------------------->\n    <!-- Radiation -->\n    <div class=\"widget-section-head\"> \n      <p class=\"widget-section-label\"><span class=\"large-icon\">&#9728;<\/span>Radiation<\/p>\n    <\/div>\n  \n    <div class=\"metric-grid\">\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Incoming solar<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-solar-in\">\u2014<span class=\"unit\">W\/m\u00b2<\/span><\/p>\n        <p class=\"metric-sub\">Adj. Boom <span style=\"padding: 4px\">\u00b7<\/span> Uplooking PSP<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Reflected solar<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-solar-out\">\u2014<span class=\"unit\">W\/m\u00b2<\/span><\/p>\n        <p class=\"metric-sub\">Adj. Boom <span style=\"padding: 4px\">\u00b7<\/span> Downlooking PSP<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Surface Albedo<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-albedo\">\u2014<\/p>\n        <p class=\"metric-sub\">Adj. Boom <span style=\"padding: 4px\">\u00b7<\/span> Up&thinsp;\/&thinsp;Down PSPs<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Incoming Longwave<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-longwave-in\">\u2014<span class=\"unit\">W\/m\u00b2<\/span><\/p>\n        <p class=\"metric-sub\">Platform <span style=\"padding: 4px\">\u00b7<\/span> Uplooking PIR<\/p>\n      <\/div>\n      <div class=\"metric-card\">\n        <p class=\"metric-label\">Surface Temperature<\/p>\n        <p class=\"metric-value loading-val\" id=\"v-surface-temp\">\u2014<span class=\"unit\">\u00b0C<\/span><\/p>\n        <p class=\"metric-sub\">Fixed Boom <span style=\"padding: 4px\">\u00b7<\/span> Apogee SI-111<\/p>\n      <\/div>\n    <\/div>\n  \n    <!--------------------------------------------------------------------------------------------------->\n    <!-- Percent of median gauges -->\n  <!-- \n    <div class=\"widget-section-head\"> \n      <p class=\"widget-section-label\">vs. 1991\u20132020 median (water year to date)<\/p>\n    <\/div>\n  \n    <div class=\"gauge-grid\">\n      <div class=\"gauge-card\">\n        <p class=\"gauge-label\">SWE (MAYBE DO PEAK SWE THIS WY?)<\/p>\n        <div class=\"gauge-track\"><div class=\"gauge-fill\" id=\"g-swe\" style=\"background:var(--snow-mid)\"><\/div><\/div>\n        <div class=\"gauge-row\"><span class=\"gauge-pct\" id=\"g-swe-pct\">\u2014%<\/span><span class=\"gauge-of\">of median<\/span><\/div>\n      <\/div>\n      <div class=\"gauge-card\">\n        <p class=\"gauge-label\">Snow depth<\/p>\n        <div class=\"gauge-track\"><div class=\"gauge-fill\" id=\"g-depth\" style=\"background:var(--snow-mid)\"><\/div><\/div>\n        <div class=\"gauge-row\"><span class=\"gauge-pct\" id=\"g-depth-pct\">\u2014%<\/span><span class=\"gauge-of\">of median<\/span><\/div>\n      <\/div>\n      <div class=\"gauge-card\">\n        <p class=\"gauge-label\">Precip. to date<\/p>\n        <div class=\"gauge-track\"><div class=\"gauge-fill\" id=\"g-precip\" style=\"background:var(--snow-mid)\"><\/div><\/div>\n        <div class=\"gauge-row\"><span class=\"gauge-pct\" id=\"g-precip-pct\">\u2014%<\/span><span class=\"gauge-of\">of median<\/span><\/div>\n      <\/div> -->\n      <!-- Peak SWE to date -->\n      <!-- <div class=\"metric-card\" id=\"card-swe-max\" style=\"border-color: rgba(91,163,208,0.35);\">\n        <p class=\"metric-label\">Peak SWE \u00b7 WY <span id=\"v-swe-max-wy\">\u2014<\/span><\/p>\n        <p class=\"metric-value loading-val\" id=\"v-swe-max\">\u2014<span class=\"unit\">in<\/span><\/p>\n        <p class=\"metric-sub\" id=\"v-swe-max-ts\">Hourly rolling mean<\/p>\n      <\/div>\n    <\/div>\n     -->\n  \n    <!-- Footer -->\n    <div class=\"widget-footer\">\n      <span>Jeff Dozier Snow Study Site \u00b7 <a href=\"https:\/\/snow.ucsb.edu\">snow.ucsb.edu<\/a><\/span>\n      <span id=\"footer-timestamp\">Last updated: \u2014<\/span>\n    <\/div>\n  \n  <\/div><!-- .widget-root -->\n  \n  <script>\n  \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  \/\/  CONFIGURATION \u2014 edit these values to match your actual proxy setup\n  \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  const CONFIG = {\n  \n    \/\/ Base URL of your PHP proxy script\n    \/\/ e.g. 'https:\/\/snow.ucsb.edu\/query.php'\n    PROXY_URL: 'https:\/\/snow.ucsb.edu\/wp-content\/themes\/twentytwelve-child\/current-conditions.php',\n  \n    \/\/ Output format \u2014 matches your proxy's _output param\n    OUTPUT_FORMAT: 'json',\n  \n    \/\/v How often to refresh data (milliseconds). 900000 = 15 min.\n    REFRESH_INTERVAL_MS: 300000,     \/\/ 5 minutes\n  \n  \n    \/\/ \u2500\u2500 MEASUREMENT TABLE NAMES \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    \/\/ Replace each placeholder with the table\/measurement name accepted by your php script\n    \/\/ current-conditions.php script is configured to map these to the most recently updated table, \n    \/\/ so just define them as themselves here...\n    TABLES: {\n      snow5min:     'snow5min',                  \n      snow1min:     'snow1min',                                  \n      atmosphere:   'atmosphere',   \n      wind:         'wind',          \n      radiation:    'radiation',    \n    },\n  \n    \/\/ \u2500\u2500 CSV COLUMN NAMES \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    \/\/ Replace each placeholder with the exact column header from your CSV output.\n    \/\/ These are the field names returned by the proxy for each table.\n    COLUMNS: {\n      \/\/ 1-min table columns\n      timestamp1minSnow:  'TIMESTAMP',\n      sweSSG:             'ssg_swe',                         \/\/ e.g. 'SSG_SnowPillow_SWE' : raw unit: cm\n      snowDepthSouth:     'snodar_snow_depth',               \/\/ e.g. 'snodar_snow_depth' : raw unit: cm\n  \n      \/\/ 5-min snow table columns\n      timestamp5minSnow:  'TIMESTAMP',\n      snowDepthNorth:     'LaserNorthSnowDepth',             \/\/ e.g. 'snodar_snow_depth' : raw unit: cm \n      sweDWR:             'SnowPillow_SWE',                  \/\/ e.g. 'DWR_SnowPillow_SWE' : raw unit: cm\n  \n      \/\/ Atmosphere table columns\n      timestamp1minAtmos: 'TIMESTAMP',\n      airTemp:            'Plat_Temp',                       \/\/ \u00b0C \n      relHumidity:        'Plat_RH',                         \/\/ %\n      pressure:           'ATMP',                            \/\/ mb\n  \n      \/\/ Wind table columns\n      timestamp1minWind:  'TIMESTAMP',\n      windSpeed:          'YoungWindSpeed',                  \/\/ raw unit: m\/s \n      windDir:            'YoungWindDir',                    \/\/ degrees (cardinal computed in js)\n  \n      \/\/ Radiation table columns\n      timestamp1minRad:   'TIMESTAMP',\n      solarIn:            'UpLookingAdjBoomClear',           \/\/ 'UpLookingPlatformClear', W\/m\u00b2\n      solarOut:           'DownLookingAdjBoomClear',         \/\/ W\/m\u00b2\n      longwaveIn:         'PIR',                             \/\/ W\/m\u00b2\n      surfaceTemp:        'SI111TargetTemp',                 \/\/ \u00b0C\n    },\n  \n    \/\/ \u2500\u2500 RAW DB UNITS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    \/\/ Describe what units the DB stores each value in so the widget\n    \/\/ can convert correctly for whichever display system is active.\n    RAW_UNITS: {\n      snowDepthIsCm:   true,   \/\/ true = cm, false = inches\n      sweIsCm:         true,   \/\/ true = cm, false = inches\n      tempIsC:         true,   \/\/ true = \u00b0C, false = \u00b0F\n      windIsMps:       true,   \/\/ true = m\/s, false = mph or kt \n      meltIsMmhr:      true,   \/\/ true = mm\/hr, false = in\/hr\n    },\n  };\n  \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  \/\/  END CONFIGURATION\n  \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n  \n  \n  \/\/ \u2500\u2500 Unit system state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ 'imperial' or 'metric'. All raw SI values are stored here after each fetch\n  \/\/ and re-rendered instantly on toggle \u2014 no re-fetch needed.\n  \n  \/\/ let unitSystem = CONFIG.DEFAULT_UNITS;\n  let snowUnit   = 'cm'\n  let tempUnit   = '\u00b0C' ; \/\/ '\u00b0C' or '\u00b0F'\n  let windUnit   = 'm\/s'; \/\/ 'm\/s', 'mph', 'kt' \n  let lastRawData = null; \/\/ stores the last fetched raw (SI) values\n  \n  \/\/ \u2500\u2500 Water year helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \n  \/\/ Returns the starting year of the current water year (Oct 1 \u2013 Sep 30).\n  \/\/ e.g. Oct 2025 \u2192 WY2026 \u2192 returns 2026\n  function currentWaterYear() {\n    const now = new Date();\n    const m = now.getMonth(); \/\/ 0-indexed; 9 = October\n    return m >= 9 ? now.getFullYear() + 1 : now.getFullYear();\n  }\n  \n  \/\/ \u2500\u2500 Rolling-mean SWE buffer & max tracker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ The buffer holds the last N raw SWE readings (DWR pillow, in DB-native units).\n  \/\/ On each fetch cycle, the new reading is pushed in, the mean is computed,\n  \/\/ and compared against the stored WY maximum.\n  \/\/\n  \/\/ Persistence: localStorage keeps the max and its timestamp across page reloads.\n  \/\/ The stored WY tag ensures the record resets automatically each new water year.\n  \n  const SWE_ROLLING_WINDOW = 12; \/\/ number of readings for the rolling mean (12 \u00d7 5 min \u2248 1 hr)\n  const SWE_MAX_KEY        = 'sweDWE_max_v1'; \/\/ localStorage key\n  \n  let sweBuffer = []; \/\/ in-memory ring buffer of recent raw SWE readings\n  \n  function loadSweMax() {\n    try {\n      const raw = localStorage.getItem(SWE_MAX_KEY);\n      if (!raw) return null;\n      const rec = JSON.parse(raw);\n      \/\/ Discard if it belongs to a past water year\n      if (rec.wy !== currentWaterYear()) {\n        localStorage.removeItem(SWE_MAX_KEY);\n        return null;\n      }\n      return rec; \/\/ { wy, maxVal, timestamp }\n    } catch { return null; }\n  }\n  \n  function saveSweMax(maxVal, timestamp) {\n    try {\n      localStorage.setItem(SWE_MAX_KEY, JSON.stringify({\n        wy:        currentWaterYear(),\n        maxVal,                          \/\/ raw DB-native units\n        timestamp,                       \/\/ ISO string of when this max occurred\n      }));\n    } catch (e) { console.warn('Could not persist SWE max:', e); }\n  }\n  \n  \/\/ Push a new reading into the buffer and return the rolling mean (or null).\n  function updateSweRollingMean(newRawVal) {\n    if (newRawVal === null) return null;\n    sweBuffer.push(newRawVal);\n    if (sweBuffer.length > SWE_ROLLING_WINDOW) sweBuffer.shift();\n    const mean = sweBuffer.reduce((a, b) => a + b, 0) \/ sweBuffer.length;\n    return mean;\n  }\n  \n  \/\/ Compare rolling mean against stored max; persist if new record.\n  \/\/ Returns the current stored max record (possibly just updated).\n  function checkSweMax(rollingMean, observationTimestamp) {\n    if (rollingMean === null) return loadSweMax();\n    const stored = loadSweMax();\n    if (!stored || rollingMean > stored.maxVal) {\n      saveSweMax(rollingMean, observationTimestamp || new Date().toISOString());\n      return loadSweMax();\n    }\n    return stored;\n  }\n  \n  \/\/ \u2500\u2500 Conversion helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \n  const conv = {\n    \/\/ Temperature\n    cToF:    c  => c * 9\/5 + 32,\n    fToC:    f  => (f - 32) * 5\/9,\n  \n    \/\/ Length\n    cmToIn:  cm => cm \/ 2.54,\n    inToCm:  i  => i * 2.54,\n    cmToM:   cm => cm \/ 100,\n    inToFt:  i  => i \/ 12,\n  \n    \/\/ Speed\n    msToMph: ms => ms * 2.23694,\n    msToKt: ms => ms * 1.94384,\n    msToMs:  ms => ms, \/\/ identity \u2014 raw value is already m\/s\n    mphToMs: mp => mp \/ 2.23694,\n  \n    \/\/ Precipitation rate\n    mmhrToInhr: mm => mm \/ 25.4,\n  };\n  \n  function degToCardinal(deg) {\n    const dirs = ['N','NNE','NE','ENE','E','ESE','SE','SSE','S','SSW','SW','WSW','W','WNW','NW','NNW'];\n    return dirs[Math.round(deg \/ 22.5) % 16];\n  }\n  \n  \n  \/\/ \u2500\u2500 Unit display definitions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ For each measured quantity, defines display value and unit label per system.\n  \/\/ Input is always the raw DB value (SI or as configured in RAW_UNITS).\n  \n  function display(quantity, rawValue) {\n    if (rawValue === null) return { val: null, unit: '' };\n    const RU = CONFIG.RAW_UNITS;\n  \n    switch (quantity) {\n  \n      case 'snowDepth': {\n        \/\/ Raw: cm or in (per RU.snowDepthIsCm)\n        const cm = RU.snowDepthIsCm ? rawValue : conv.inToCm(rawValue);\n        return snowUnit === 'in'\n          ? { val: conv.cmToIn(cm), unit: 'in', dec: 1 }\n          : { val: cm,              unit: 'cm', dec: 1 };\n      }\n  \n      case 'swe': {\n        \/\/ Raw: cm or in (per RU.sweIsCm)\n        const cm = RU.sweIsCm ? rawValue : conv.inToCm(rawValue);\n        return snowUnit === 'in'\n          ? { val: conv.cmToIn(cm), unit: 'in', dec: 1 }\n          : { val: cm,              unit: 'cm', dec: 1 };\n      }\n  \n      case 'temp': {\n        \/\/ Raw: \u00b0C or \u00b0F (per RU.tempIsC)\n        const c = RU.tempIsC ? rawValue : conv.fToC(rawValue);\n        return tempUnit === '\u00b0F'\n          ? { val: conv.cToF(c), unit: '\u00b0F', dec: 1 }\n          : { val: c,            unit: '\u00b0C', dec: 1 };\n      }\n  \n      case 'windSpeed': {\n        const ms = RU.windIsMps ? rawValue : conv.mphToMs(rawValue);\n  \n        if (windUnit === 'kt') {\n          return { val: conv.msToKt(ms), unit: 'kt', dec: 1 };\n        }\n  \n        if (windUnit === 'mph') {\n          return { val: conv.msToMph(ms), unit: 'mph', dec: 1 };\n        }\n  \n        return { val: ms, unit: 'm\/s', dec: 1 };\n    }\n  \n      case 'pressure':\n        \/\/ mb in both systems (hPa = mb)\n        return { val: rawValue, unit: 'mb', dec: 0 };\n  \n      case 'radiation':\n        \/\/ W\/m\u00b2 in both systems\n        return { val: rawValue, unit: 'W\/m\u00b2', dec: 0 };\n  \n      default:\n        return { val: rawValue, unit: '', dec: 1 };\n    }\n  }\n  \n  \/\/ \u2500\u2500 DOM helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \n  function setVal(id, quantity, rawValue) {\n    const el = document.getElementById(id);\n    if (!el) return;\n    const d = display(quantity, rawValue);\n    const unitHtml = `<span class=\"unit\">${d.unit}<\/span>`;\n    if (d.val === null) {\n      el.innerHTML = '\u2014' + unitHtml;\n      return;\n    }\n    el.classList.remove('loading-val');\n    el.innerHTML = Number(d.val).toFixed(d.dec ?? 1) + unitHtml;\n  }\n  \n  function setGauge(fillId, pctId, pct) {\n    if (pct === null) return;\n    const fill = document.getElementById(fillId);\n    const label = document.getElementById(pctId);\n    if (fill) {\n      fill.style.width = Math.min(pct \/ 150 * 100, 100) + '%';\n      fill.style.background = pct < 60 ? 'var(--accent-red)' : pct < 85 ? 'var(--accent-amber)' : 'var(--snow-mid)';\n    }\n    if (label) label.textContent = Math.round(pct) + '%';\n  }\n  \n  function setStatus(state, text) {\n    const dot  = document.getElementById('status-dot');\n    const span = document.getElementById('status-text');\n    dot.className = 'status-dot ' + (state === 'ok' ? '' : state);\n    span.textContent = text;\n  }\n  \n  function showError(msg) {\n    const el = document.getElementById('error-banner');\n    el.style.display = 'block';\n    el.textContent = '\u26a0 ' + msg;\n    setStatus('error', 'Data unavailable');\n  }\n  \n  function clearError() {\n    document.getElementById('error-banner').style.display = 'none';\n  }\n  \n  \/\/ \u2500\u2500 Render from stored raw data \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ Called both after a fetch and on unit toggle \u2014 no re-fetch needed.\n  \n  function renderConditions(raw) {\n    if (!raw) return;\n  \n    \/\/ Snow:\n    setVal('v-depth-south', 'snowDepth', raw.snowDepthSouth);\n    setVal('v-swe-dwr', 'swe', raw.sweDWR);\n    setVal('v-depth-south-change', 'snowDepth', raw.snowDepthSouthChange); \n    setVal('v-swe-dwr-change', 'swe', raw.sweDWRChange);              \n    \n    setVal('v-depth-north', 'snowDepth', raw.snowDepthNorth);\n    setVal('v-swe-ssg', 'swe', raw.sweSSG);\n    setVal('v-depth-north-change', 'snowDepth', raw.snowDepthNorthChange);   \n    setVal('v-swe-ssg-change', 'swe', raw.sweSSGChange);               \n  \n  \n    \/\/ Atmosphere:\n    setVal('v-airtemp', 'temp',      raw.airTemp);\n    setVal('v-wind', 'windSpeed', raw.windSpeed);\n    setVal('v-pressure', 'pressure',  raw.pressure);\n    \n    \/\/ RH \u2014 unit-independent\n    if (raw.rh !== null) {\n      const el = document.getElementById('v-relhum');\n      el.classList.remove('loading-val');\n      el.innerHTML = Math.round(raw.rh) + '<span class=\"unit\">%<\/span>';\n    }\n  \n    \/\/ Wind direction \u2014 unit-independent\n    if (raw.windDir !== null) {\n      const el = document.getElementById('v-winddir');\n      el.classList.remove('loading-val');\n      el.textContent = degToCardinal(raw.windDir);\n    }\n    \/\/ Radiation:\n    setVal('v-solar-in', 'radiation', raw.solarIn);\n    setVal('v-solar-out', 'radiation', raw.solarOut);\n    setVal('v-longwave-in',  'radiation', raw.longwaveIn);\n    setVal('v-surface-temp', 'temp', raw.surfaceTemp);\n  \n    \/\/ Albedo \u2014 unit-independent ratio\n    if (raw.solarIn !== null && raw.solarOut !== null && raw.solarIn > 5) {\n      const el = document.getElementById('v-albedo');\n      el.classList.remove('loading-val'); \n      el.innerHTML = (raw.solarOut \/ raw.solarIn).toFixed(2); \n    }\n  \n    \/\/ what do I need to do with these??? \n    \/\/ timestamp1minSnow:  'TIMESTAMP',\n    \/\/   \/\/ 5-min snow table columns\n    \/\/   timestamp5minSnow:  'TIMESTAMP',\n    \n    \/\/   \/\/ Atmosphere table columns\n    \/\/   timestamp1minAtmos: 'TIMESTAMP',\n  \n    \/\/   \/\/ Wind table columns\n    \/\/   timestamp1minWind:  'TIMESTAMP',\n  \n    \/\/   \/\/ Radiation table columns\n    \/\/   timestamp1minRad:   'TIMESTAMP',\n  \n  \n    \/\/ Peak SWE WY card \u2014 reads from localStorage, re-renders on unit toggle\n    const sweMaxRec = loadSweMax();\n    const sweMaxEl  = document.getElementById('v-swe-max');\n    const sweMaxTs  = document.getElementById('v-swe-max-ts');\n    const sweMaxWy  = document.getElementById('v-swe-max-wy');\n    if (sweMaxEl && sweMaxRec) {\n      const d = display('swe', sweMaxRec.maxVal);\n      const unitHtml = `<span class=\"unit\">${d.unit}<\/span>`;\n      sweMaxEl.classList.remove('loading-val');\n      sweMaxEl.innerHTML = Number(d.val).toFixed(d.dec ?? 2) + unitHtml;\n      if (sweMaxWy) sweMaxWy.textContent = sweMaxRec.wy;\n      if (sweMaxTs) {\n        const dt = new Date(sweMaxRec.timestamp);\n        sweMaxTs.textContent = 'Peak: ' + dt.toLocaleString('en-US', {\n          month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit'\n        });\n      }\n    }\n  \n    \/\/ Gauges (% of median \u2014 unit-independent ratios)\n    \/\/ TODO: Replace nulls with real median comparison values from your DB.\n    \/\/ Options:\n    \/\/   A) Add a medians table query to CONFIG.TABLES above\n    \/\/   B) Compute from historical data in the DB\n    \/\/   C) Hardcode seasonal normals updated each water year\n    setGauge('g-swe',    'g-swe-pct',    null); \/\/ e.g. (raw.sweDWR \/ medianSWE) * 100\n    setGauge('g-depth',  'g-depth-pct',  null); \/\/ e.g. (raw.snowDepth \/ medianDepth) * 100\n    setGauge('g-precip', 'g-precip-pct', null); \/\/ e.g. (ytdPrecip \/ medianYtdPrecip) * 100\n  }\n  \n  \/\/ \u2500\u2500 Unit toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ -- All fields [page-wide controls; disabled]\n  \/\/ function setUnitSystem(system) {\n  \/\/   unitSystem = system;\n  \/\/   document.getElementById('btn-us').classList.toggle('active',     system === 'us');\n  \/\/   document.getElementById('btn-metric').classList.toggle('active', system === 'metric');\n  \/\/   \/\/ Show the mph\/kt sub-toggle only in US mode\n  \/\/    \/\/const wrapEl = document.getElementById('wind-toggle-wrap');\n  \/\/   \/\/ if (wrapEl) wrapEl.style.display = system === 'us' ? 'flex' : 'none';\n  \/\/   renderConditions(lastRawData);\n  \/\/ }\n  \n  function updateUnitLabels() {\n    const tempUnitEls = [\n      'v-airtemp-unit',\n      'v-swe-max-unit'\n    ];\n  \n    const snowUnitEls = [\n      'v-depth-south-unit',\n      'v-depth-south-change-unit',\n      'v-swe-dwr-unit',\n      'v-swe-dwr-change-unit',\n      'v-depth-north-unit',\n      'v-depth-north-change-unit',\n      'v-swe-ssg-unit',\n      'v-swe-ssg-change-unit'\n    ];\n  \n    const windUnitEl = document.getElementById('v-wind-unit');\n  \n    tempUnitEls.forEach(id => {\n      const el = document.getElementById(id);\n      if (el) el.textContent = tempUnit;\n    });\n  \n    snowUnitEls.forEach(id => {\n      const el = document.getElementById(id);\n      if (el) el.textContent = snowUnit;\n    });\n  \n    if (windUnitEl) windUnitEl.textContent = windUnit;\n  }\n  \n  \n  function setAtmosPreset(mode) {\n    if (mode === 'metric') {\n      tempUnit = '\u00b0C';\n      windUnit = 'm\/s';\n    } else if (mode === 'kt') {\n      tempUnit = '\u00b0F';\n      windUnit = 'kt';\n    } else if (mode === 'mph') {\n      tempUnit = '\u00b0F';\n      windUnit = 'mph';\n    }\n  \n    document.getElementById('btn-atmos-metric').classList.toggle('active', mode === 'metric');\n    document.getElementById('btn-atmos-us-kt').classList.toggle('active', mode === 'kt');\n    document.getElementById('btn-atmos-us-mph').classList.toggle('active', mode === 'mph');\n  \n    renderConditions(lastRawData);\n    updateUnitLabels();\n  }\n  \n  \n  \/\/ -- Snow units:\n  function setSnowUnit(unit) {\n    snowUnit = unit;\n    document.getElementById('btn-snow-cm').classList.toggle('active', unit === 'cm');\n    document.getElementById('btn-snow-in').classList.toggle('active', unit === 'in');\n    \n    renderConditions(lastRawData);\n    updateUnitLabels();\n  }\n  \n  \n  \n  \/\/ \u2500\u2500 CSV parser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \n  function parseCSV(text) {\n    const lines = text.trim().split('\\n').filter(l => l.trim());\n    if (lines.length < 2) return [];\n    const headers = lines[0].split(',').map(h => h.trim().replace(\/^\"|\"$\/g, ''));\n    return lines.slice(1).map(line => {\n      const vals = line.split(',').map(v => v.trim().replace(\/^\"|\"$\/g, ''));\n      const row = {};\n      headers.forEach((h, i) => row[h] = vals[i] ?? '');\n      return row;\n    });\n  }\n  \n  function latestRow(rows) { return rows.length ? rows[rows.length - 1] : null; }\n  function num(val) { const n = parseFloat(val); return isNaN(n) ? null : n; }\n  \n  \/\/ \u2500\u2500 Fetch one table from proxy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \n  \/\/ async function fetchTable(tableName, interval = 60) {\n  \/\/   const url = new URL(CONFIG.PROXY_URL);\n  \/\/   url.searchParams.set('_output', CONFIG.OUTPUT_FORMAT);\n  \/\/   url.searchParams.set('table', tableName);\n  \/\/   url.searchParams.set('interval', interval);\n  \n  \/\/   \/\/ Fetch last 2 hours, take the most recent row\n  \/\/   const now   = new Date();\n  \/\/   const start = new Date(now - 2 * 3600 * 1000);\n  \/\/   url.searchParams.set('start', start.toISOString().slice(0, 16).replace('T', ' '));\n  \/\/   url.searchParams.set('end',   now.toISOString().slice(0, 16).replace('T', ' '));\n  \n  \/\/   const res = await fetch(url.toString());\n  \/\/   if (!res.ok) throw new Error(`HTTP ${res.status} for table \"${tableName}\"`);\n  \/\/   return parseCSV(await res.text());\n  \/\/ }\n  \n  async function fetchTable(tableName) {\n    const url = new URL(CONFIG.PROXY_URL, window.location.origin);\n    url.searchParams.set('table', tableName);\n  \n    const res = await fetch(url.toString());\n  \n    if (!res.ok) {\n      throw new Error(`HTTP ${res.status} for table \"${tableName}\"`);\n    }\n  \n    return await res.json();\n  \n  }\n  \n  \/\/ Calculate 24-hour changes:\n  function diffNowMinusPrev(current, previous) {\n    if (current === null || previous === null) return null;\n    return current - previous;\n  }\n  \n  \/\/ \u2500\u2500 Main data loader \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \n  async function loadConditions() {\n    setStatus('loading', 'Fetching data\u2026');\n    clearError();\n  \n    const C = CONFIG.COLUMNS;\n  \n    try {\n      \/\/ const [depthRows, atmosRows, windRows, radRows, surfRows, lysiRows] = await Promise.all([\n      const [snow5Data, snow1Data, atmosData, windData, radData] = await Promise.all([\n        fetchTable(CONFIG.TABLES.snow5min),\n        fetchTable(CONFIG.TABLES.snow1min),\n        fetchTable(CONFIG.TABLES.atmosphere),\n        fetchTable(CONFIG.TABLES.wind),\n        fetchTable(CONFIG.TABLES.radiation),\n      ]);\n  \n      const snow5 = snow5Data.latest;\n      const snow5Prev = snow5Data.previous24h;\n  \n      const snow1 = snow1Data.latest;\n      const snow1Prev = snow1Data.previous24h;\n  \n      const atmos = atmosData.latest;\n      const wind  = windData.latest;\n      const rad   = radData.latest;\n  \n  \n      \/\/ Store all raw (SI\/DB-native) values \u2014 conversions happen at render time\n      lastRawData = {\n        snowDepthSouth: snow1 ? num(snow1[C.snowDepthSouth]) : null,\n        snowDepthNorth: snow5 ? num(snow5[C.snowDepthNorth]) : null,\n        sweSSG:         snow1 ? num(snow1[C.sweSSG])         : null,\n        sweDWR:         snow5 ? num(snow5[C.sweDWR])         : null,\n  \n        snowDepthSouthChange: snow1 && snow1Prev\n          ? diffNowMinusPrev(num(snow1[C.snowDepthSouth]), num(snow1Prev[C.snowDepthSouth]))\n          : null,\n  \n        snowDepthNorthChange: snow5 && snow5Prev\n          ? diffNowMinusPrev(num(snow5[C.snowDepthNorth]), num(snow5Prev[C.snowDepthNorth]))\n          : null,\n  \n        sweSSGChange: snow1 && snow1Prev\n          ? diffNowMinusPrev(num(snow1[C.sweSSG]), num(snow1Prev[C.sweSSG]))\n          : null,\n  \n        sweDWRChange: snow5 && snow5Prev\n          ? diffNowMinusPrev(num(snow5[C.sweDWR]), num(snow5Prev[C.sweDWR]))\n          : null,\n  \n        airTemp:        atmos ? num(atmos[C.airTemp])        : null,\n        rh:             atmos ? num(atmos[C.relHumidity])    : null,\n        pressure:       atmos ? num(atmos[C.pressure])       : null,\n  \n        windSpeed:      wind  ? num(wind[C.windSpeed])       : null,\n        windDir:        wind  ? num(wind[C.windDir])         : null,\n  \n        solarIn:        rad   ? num(rad[C.solarIn])          : null,\n        solarOut:       rad   ? num(rad[C.solarOut])         : null,\n        longwaveIn:     rad   ? num(rad[C.longwaveIn])       : null,\n        surfaceTemp:    rad   ? num(rad[C.surfaceTemp])      : null,\n  \n        timestamp:      atmos?.[C.timestamp1minAtmos] || \n                        snow5?.[C.timestamp5minSnow] ||         \/\/ Timestamps differ depending on data stream...\n                        snow1?.[C.timestamp1minSnow] ||         \/\/ Put atmosphere first \n                        wind?.[C.timestamp1minWind] ||\n                        rad?.[C.timestamp1minRad] ||\n                        null,\n      };\n  \n      \/\/ \u2500\u2500 Rolling-mean SWE max check \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n      \/\/ Push the new DWR SWE reading into the rolling buffer, compute the mean,\n      \/\/ and update the WY maximum if it's a new record.\n      \/\/ Uses DWR pillow as the primary SWE source; swap to sweSSG if preferred.\n      const rollingMean = updateSweRollingMean(lastRawData.sweDWR);\n      checkSweMax(rollingMean, lastRawData.timestamp);\n      \/\/ renderConditions will pick up the (possibly updated) max from localStorage\n  \n      renderConditions(lastRawData);\n  \n\n      \/\/ Last data timestamp:\n      const rawTimestamp = lastRawData?.timestamp;\n      const parsedDate = rawTimestamp ? new Date(rawTimestamp) : null;\n\n      \/\/ Add am\/pm formatting: \n      let timeString = '-';\n\n      if (parsedDate && !Number.isNaN(parsedDate.getTime())) {\n        let hours = parsedDate.getHours();\n        const minutes = String(parsedDate.getMinutes()).padStart(2, '0');\n        const ampm = hours >= 12 ? 'PM' : 'AM';\n\n        hours = hours % 12;\n        hours = hours ? hours : 12; \/\/ convert 0 to 12\n\n        timeString = `${hours}:${minutes} ${ampm} PST`;\n      }\n\n      const ts = parsedDate && !Number.isNaN(parsedDate.getTime())\n        ? `\n          <div style=\"text-align: right; display: inline-block; vertical-align: top;\">\n            <div>${timeString}<\/div>\n            <div>${parsedDate.getMonth() + 1}\/${parsedDate.getDate()}\/${parsedDate.getFullYear()}<\/div>\n          <\/div>\n        `\n        : '-';\n\n      document.getElementById('footer-timestamp').innerHTML = 'Last updated: ' + ts;\n\n      setStatus('ok', 'Live  \u00b7  ' + new Date().toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZoneName: 'short' }));\n  \n    } catch (err) {\n      console.error('Snow widget fetch error:', err);\n      showError('Could not load sensor data. ' + err.message);\n    }\n  }\n  \n  \/\/ \u2500\u2500 Boot & auto-refresh \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n  \/\/ setUnitSystem(CONFIG.DEFAULT_UNITS); \/\/ set initial button state\n  setSnowUnit('cm');\n  setAtmosPreset('metric');\n  loadConditions();\n  setInterval(loadConditions, CONFIG.REFRESH_INTERVAL_MS);\n  <\/script>\n  <\/body>\n  <\/html>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<hr class=\"wp-block-separator aligncenter has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><span style=\"color:#1c3048;\">Recent Posts:<\/span><\/h2>\n\n\n<ul style=\"font-size:16px;\" class=\"wp-block-latest-posts__list has-dates wp-block-latest-posts\"><li><a class=\"wp-block-latest-posts__post-title\" href=\"https:\/\/snow.ucsb.edu\/index.php\/2025\/09\/15\/2025-tlc\/\">2025 TLC<\/a><time datetime=\"2025-09-15T13:44:48-07:00\" class=\"wp-block-latest-posts__post-date\">September 15, 2025<\/time><\/li>\n<li><a class=\"wp-block-latest-posts__post-title\" href=\"https:\/\/snow.ucsb.edu\/index.php\/2025\/05\/01\/tristate-may-2025-meeting\/\">Tristate May 2025 Meeting<\/a><time datetime=\"2025-05-01T11:19:51-07:00\" class=\"wp-block-latest-posts__post-date\">May 1, 2025<\/time><\/li>\n<li><a class=\"wp-block-latest-posts__post-title\" href=\"https:\/\/snow.ucsb.edu\/index.php\/2024\/09\/16\/tristate-snow-meeting-mammoth-sep-2024\/\">Tristate snow meeting, Mammoth Sep 2024<\/a><time datetime=\"2024-09-16T08:25:10-07:00\" class=\"wp-block-latest-posts__post-date\">September 16, 2024<\/time><\/li>\n<\/ul>\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\"><\/div>\n\n\n\n<a href=\"https:\/\/snow.ucsb.edu\/index.php\/posts\/\"\n   target=\"_blank\"\n   rel=\"noopener noreferrer\"\n   style=\"display:inline-block;\n          background:#1c3048;\n          color:#fff;\n          padding:6px 16px;\n          text-decoration:none;\n          font-weight:500;\n          border-radius:999px;\n          text-align:center;\n          font-size:14px\">\n  Older Posts\n<\/a>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Current Conditions \u2014 Jeff Dozier Snow Study Site Jeff Dozier Snow Study Site \u00b7 9,633 ft | Mammoth Mountain, CA Current Conditions Fetching data\u2026 &#10053;Snowpack cm in Snow Depth \u2014cm South Side \u00b7 SNOdar 24-Hour Snow Depth Change \u2014cm South Side \u00b7 SNOdar Snow Water Equivalent \u2014cm South Side \u00b7 DWR Snow Pillow 24-Hour SWE [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2139","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/pages\/2139","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/comments?post=2139"}],"version-history":[{"count":154,"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/pages\/2139\/revisions"}],"predecessor-version":[{"id":2359,"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/pages\/2139\/revisions\/2359"}],"wp:attachment":[{"href":"https:\/\/snow.ucsb.edu\/index.php\/wp-json\/wp\/v2\/media?parent=2139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}