// ------------------------------------------------------------------------
//  components/DayTabs.js - Day-tab strip, pro-prompt card, confidence
//  band bar, and filter-profile row for the UTCIForecast app.
//
//  Extracted from app.js to keep the main component under the AI edit
//  safe-zone. All state lives in useAppState - this component is purely
//  presentational and receives everything it needs as props.
//
//  Props:
//    days                   - array of day objects from buildHourlyRows
//    selectedDay            - index of the active day tab
//    setSelectedDay         - setter for selectedDay
//    isPro                  - boolean Pro status
//    FREE_DAYS              - number of free days
//    proPromptDay           - index of locked day that was clicked
//    setProPromptDay        - setter for proPromptDay
//    proPromptSource        - string key for upsell copy
//    setProPromptSource     - setter for proPromptSource
//    activeProfile          - current filter profile key
//    activateProfile        - function to switch profile
//    activeCols             - effective column set for current profile
//    visibleCols            - object of col-key -> boolean visibility
//    activityOptions        - dropdown options for Activities selector
//    placeOptions           - dropdown options for Places selector
//    workOptions            - dropdown options for Work selector
//    activityValue          - current activity dropdown value
//    activityLabel          - current activity dropdown label
//    placeValue             - current place dropdown value
//    placeLabel             - current place dropdown label
//    workValue              - current work dropdown value
//    workLabel              - current work dropdown label
//    outdoorsVariant        - current outdoors sub-variant key
//    setOutdoorsVariantAndSave - setter that also persists to localStorage
//    setActiveProfile       - raw setter for activeProfile
//    setVisibleCols         - raw setter for visibleCols
//    setIndoorMode          - setter for indoorMode
//    setIndoorManaged       - setter for indoorManaged
//    dayTabsRef             - ref for the scrollable tab strip element
//    canScrollLeft          - boolean for left-fade chevron
//    canScrollRight         - boolean for right-fade chevron
//    scrollDayTabs          - function(dir) to scroll strip left/right
// ------------------------------------------------------------------------

import { h, Fragment } from '../../vendor/preact.js';
import { useRef, useEffect } from '../../vendor/preact-hooks.js';
import htm from '../../vendor/htm.js';
import { confidenceBand } from '../utils.js';
import { FREE_DAYS, FILTER_PROFILES, OUTDOORS_VARIANTS, profileButtonOrder, activityVariantKeys, placeVariantKeys, workVariantKeys } from '../config.js';
import { CloudIcon, PrecipIcon, CustomSelect } from '../components.js';

const html = htm.bind(h);

// Converts a base RGB colour into the same 135° gradient used by the thermal
// bands legend: 50% white blend to pastelise, then a subtle light→dark sweep.
function weatherGradient(r, g, b) {
  const blend   = (c) => Math.round(c + (255 - c) * 0.82);
  const [mr, mg, mb] = [blend(r), blend(g), blend(b)];
  const lighten = (c) => Math.min(255, Math.round(c + (255 - c) * 0.30));
  const darken  = (c) => Math.round(c * 0.96);
  const light = `rgb(${lighten(mr)},${lighten(mg)},${lighten(mb)})`;
  const mid   = `rgb(${mr},${mg},${mb})`;
  const dark  = `rgb(${darken(mr)},${darken(mg)},${darken(mb)})`;
  return `linear-gradient(135deg, ${light} 0%, ${mid} 60%, ${dark} 100%)`;
}

// Active-tab variant: a more solid (less pastelised) version of the weather
// colour, drawn as a radial gradient whose strong colour sits at the outer
// edge and softens toward a lighter centre — so the hue reads as radiating
// inward from the outside of the tab.
function weatherGradientActive(r, g, b) {
  const blend   = (c) => Math.round(c + (255 - c) * 0.42);
  const [mr, mg, mb] = [blend(r), blend(g), blend(b)];
  const lighten = (c) => Math.min(255, Math.round(c + (255 - c) * 0.38));
  const center  = `rgb(${lighten(mr)},${lighten(mg)},${lighten(mb)})`;
  const edge    = `rgb(${mr},${mg},${mb})`;
  return `radial-gradient(circle at 50% 50%, ${center} 0%, ${center} 28%, ${edge} 100%)`;
}

export function DayTabs({
  days,
  selectedDay, setSelectedDay,
  isPro,
  proPromptDay, setProPromptDay,
  proPromptSource, setProPromptSource,
  activeProfile, activateProfile, activeCols,
  visibleCols,
  activityOptions, placeOptions, workOptions,
  activityValue, activityLabel,
  placeValue, placeLabel,
  workValue, workLabel,
  outdoorsVariant, setOutdoorsVariantAndSave,
  setActiveProfile, setVisibleCols,
  setIndoorMode, setIndoorManaged, setBuildingType,
  dayTabsRef, canScrollLeft, canScrollRight, scrollDayTabs,
}) {
  const profileScrollRef = useRef(null);
  const profileWrapRef   = useRef(null);

  useEffect(() => {
    const el   = profileScrollRef.current;
    const wrap = profileWrapRef.current;
    if (!el) return;
    let isDown = false, startX = 0, startScroll = 0, hasDragged = false;

    const updateFades = () => {
      if (!wrap) return;
      wrap.classList.toggle('fade-left',  el.scrollLeft > 1);
      wrap.classList.toggle('fade-right', el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
    };

    const onMouseDown = (e) => {
      if (!el.contains(e.target) || e.button !== 0) return;
      isDown = true; hasDragged = false;
      startX = e.clientX; startScroll = el.scrollLeft;
      document.body.style.userSelect = 'none';
      document.body.style.webkitUserSelect = 'none';
    };
    const onMouseMove = (e) => {
      if (!isDown) return;
      const dx = e.clientX - startX;
      if (Math.abs(dx) > 5) {
        hasDragged = true;
        el.style.cursor = 'grabbing';
        el.scrollLeft = startScroll - dx;
      }
    };
    const onMouseUp = () => {
      if (!isDown) return;
      isDown = false;
      el.style.cursor = '';
      document.body.style.userSelect = '';
      document.body.style.webkitUserSelect = '';
    };
    const onClickCapture = (e) => {
      if (hasDragged) { e.stopPropagation(); e.preventDefault(); hasDragged = false; }
    };

    el.addEventListener('scroll', updateFades);
    updateFades(); // set initial fade state

    document.addEventListener('mousedown', onMouseDown);
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup',   onMouseUp);
    el.addEventListener('click', onClickCapture, true);
    return () => {
      el.removeEventListener('scroll', updateFades);
      document.removeEventListener('mousedown', onMouseDown);
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup',   onMouseUp);
      el.removeEventListener('click', onClickCapture, true);
    };
  }, []);

  return html`
    <${Fragment}>

      <div class="filter-profiles">
        <div class="profile-scroll-wrap" ref=${profileWrapRef}>
        <div class="profile-scroll" ref=${profileScrollRef}>
        ${profileButtonOrder.slice(0, 3).map((key) => {
          const profile = FILTER_PROFILES[key];
          const locked  = profile.proOnly && !isPro;
          return html`
            <button
              key=${key}
              class=${`profile-btn${activeProfile === key ? ' active' : ''}${locked ? ' locked' : ''}`}
              style=${{ opacity: locked ? 0.6 : 1, cursor: locked ? 'not-allowed' : 'pointer', position: 'relative' }}
              title=${locked ? `🔒 ${profile.label} is part of SunScope Extra` : ''}
              onClick=${() => {
                if (locked) {
                  setProPromptSource(`profile:${key}`);
                  setProPromptDay(0);
                  return;
                }
                activateProfile(key);
              }}
            >
              <span class="profile-btn-scene" style=${{ background: profile.scene }}>${profile.scene.includes('url(') ? null : profile.icon}</span>
              <span class="profile-btn-label">${profile.label}${locked ? ' 🔒' : ''}</span>
            </button>`;
        })}
        <span class="profile-divider" aria-hidden="true"></span>
        <${CustomSelect}
          key="places"
          value=${placeValue}
          isOn=${activeProfile === 'outdoors' && placeVariantKeys.includes(outdoorsVariant)}
          noHide=${true}
          hideLabel="Places"
          buttonLabel=${placeValue === 'off' ? 'Places' : `${placeLabel}`}
          grpClass="profile-card"
          sceneStyle=${{ background: placeValue !== 'off' && OUTDOORS_VARIANTS[placeValue]?.scene ? OUTDOORS_VARIANTS[placeValue].scene : "url('assets/images/profiles/places.png') center / cover no-repeat, linear-gradient(160deg,#98ccc0,#c4e4dc)" }}
          sceneContent=${null}
          options=${placeOptions}
          onChange=${(v) => {
            if (v === 'off') { activateProfile('basic'); return; }
            if (OUTDOORS_VARIANTS[v]?.proOnly && !isPro) {
              setProPromptSource(`variant:${v}`);
              setProPromptDay(0);
              return;
            }
            try { localStorage.setItem('sunscope_profile', 'outdoors'); } catch (e) { /* ignore */ }
            setActiveProfile('outdoors');
            setOutdoorsVariantAndSave(v);
            setVisibleCols({ ...OUTDOORS_VARIANTS[v].cols });
            setIndoorMode('off');
            setIndoorManaged(false);
          }}
        />
        <${CustomSelect}
          key="activities"
          value=${activityValue}
          isOn=${activeProfile === 'outdoors' && activityVariantKeys.includes(outdoorsVariant)}
          noHide=${true}
          hideLabel="Activities"
          buttonLabel=${activityValue === 'off' ? 'Activities' : `${activityLabel}`}
          grpClass="profile-card"
          sceneStyle=${{ background: activityValue !== 'off' && OUTDOORS_VARIANTS[activityValue]?.scene ? OUTDOORS_VARIANTS[activityValue].scene : "url('assets/images/profiles/activities.png') center / cover no-repeat, linear-gradient(160deg,#e0c0a0,#f0d8c0)" }}
          sceneContent=${null}
          options=${activityOptions}
          onChange=${(v) => {
            if (v === 'off') { activateProfile('basic'); return; }
            if (OUTDOORS_VARIANTS[v]?.proOnly && !isPro) {
              setProPromptSource(`variant:${v}`);
              setProPromptDay(0);
              return;
            }
            try { localStorage.setItem('sunscope_profile', 'outdoors'); } catch (e) { /* ignore */ }
            setActiveProfile('outdoors');
            setOutdoorsVariantAndSave(v);
            setVisibleCols({ ...OUTDOORS_VARIANTS[v].cols });
            setIndoorMode('off');
            setIndoorManaged(false);
          }}
        />
        <${CustomSelect}
          key="work"
          value=${workValue}
          isOn=${activeProfile === 'farming' || (activeProfile === 'outdoors' && workVariantKeys.includes(outdoorsVariant))}
          noHide=${true}
          hideLabel="Work"
          buttonLabel=${workValue === 'off' ? 'Work' : `${workLabel}`}
          grpClass="profile-card"
          sceneStyle=${{ background: workValue === 'farming' ? FILTER_PROFILES.farming.scene : workValue !== 'off' && OUTDOORS_VARIANTS[workValue]?.scene ? OUTDOORS_VARIANTS[workValue].scene : "url('assets/images/profiles/work.png') center / cover no-repeat, linear-gradient(160deg,#b0b0d4,#d0d0e8)" }}
          sceneContent=${null}
          options=${workOptions}
          onChange=${(v) => {
            if (v === 'off') { activateProfile('basic'); return; }
            if (v === 'farming') { activateProfile('farming'); return; }
            if (OUTDOORS_VARIANTS[v]?.proOnly && !isPro) {
              setProPromptSource(`variant:${v}`);
              setProPromptDay(0);
              return;
            }
            try { localStorage.setItem('sunscope_profile', 'outdoors'); } catch (e) { /* ignore */ }
            setActiveProfile('outdoors');
            setOutdoorsVariantAndSave(v);
            setVisibleCols({ ...OUTDOORS_VARIANTS[v].cols });
            if (v === 'office') {
              setBuildingType('office');
              setIndoorMode('on');
              setIndoorManaged(false);
            } else {
              setIndoorMode('off');
              setIndoorManaged(false);
            }
          }}
        />
        <span class="profile-divider" aria-hidden="true"></span>
        ${profileButtonOrder.slice(3).map((key) => {
          const profile = FILTER_PROFILES[key];
          const locked  = profile.proOnly && !isPro;
          return html`
            <button
              key=${key}
              class=${`profile-btn${activeProfile === key ? ' active' : ''}${locked ? ' locked' : ''}`}
              style=${{ opacity: locked ? 0.6 : 1, cursor: locked ? 'not-allowed' : 'pointer', position: 'relative' }}
              title=${locked ? `🔒 ${profile.label} is part of SunScope Extra` : ''}
              onClick=${() => {
                if (locked) {
                  setProPromptSource(`profile:${key}`);
                  setProPromptDay(0);
                  return;
                }
                activateProfile(key);
              }}
            >
              <span class="profile-btn-scene" style=${{ background: profile.scene }}>${profile.scene.includes('url(') ? null : profile.icon}</span>
              <span class="profile-btn-label">${profile.label}${locked ? ' 🔒' : ''}</span>
            </button>`;
        })}
        </div>
        </div>
      </div>

      <div class=${`utci-day-tabs-wrap${canScrollLeft ? ' fade-left' : ''}${canScrollRight ? ' fade-right' : ''}`}>
        <button
          class=${`utci-day-scroll left${canScrollLeft ? '' : ' hidden'}`}
          onClick=${() => scrollDayTabs(-1)}
          aria-label="Scroll days left"
          type="button">‹</button>
        <button
          class=${`utci-day-scroll right${canScrollRight ? '' : ' hidden'}`}
          onClick=${() => scrollDayTabs(1)}
          aria-label="Scroll days right"
          type="button">›</button>
      <div class="utci-day-tabs" ref=${dayTabsRef}>
        ${days.map((d, i) => {
          const band   = confidenceBand(i);
          const locked = !isPro && i >= FREE_DAYS;
          const isActive = i === selectedDay;
          const dDate  = new Date(d.key + 'T00:00Z');
          const dayName = i === 0 ? 'Today'
                        : i === 1 ? 'Tomorrow'
                        : dDate.toLocaleDateString('en-GB', { weekday: 'short', timeZone: 'UTC' });
          const utcipVals = d.rows.map(r => r.utciAdj).filter(v => isFinite(v));
          const dayHi = utcipVals.length ? Math.round(Math.max(...utcipVals)) : null;
          const dayLo = utcipVals.length ? Math.round(Math.min(...utcipVals)) : null;

          // Day-tab weather icon - use daytime rows where available
          const dayRows    = d.rows.filter(r => r.elev > 0);
          const repRows    = dayRows.length > 0 ? dayRows : d.rows;
          const dayPrecip  = repRows.reduce((s, r) => s + (r.precip || 0), 0);
          const daySnow    = repRows.reduce((s, r) => s + (r.snow   || 0), 0);
          const catCounts  = {};
          repRows.forEach(r => { if (r.cloudCat) catCounts[r.cloudCat] = (catCounts[r.cloudCat] || 0) + 1; });
          const modalCloudCat = Object.keys(catCounts).sort((a, b) => catCounts[b] - catCounts[a])[0] || 'clear';
          const midRow     = repRows[Math.floor(repRows.length / 2)];
          const repElev    = midRow ? midRow.elev : 45;
          const repDt      = midRow ? midRow.dt   : dDate;
          const showPrecip = dayPrecip >= 0.3 || daySnow >= 0.1;

          // Base RGB for each weather condition — pastelised by weatherGradient()
          const [wR, wG, wB] = (daySnow >= 0.1)                      ? [100, 160, 230]
                              : (dayHi > 38)                          ? [210,  60,  30]
                              : showPrecip                            ? [ 50, 120, 200]
                              : (dayHi > 32)                          ? [220, 110,  30]
                              : (dayHi > 26)                          ? [220, 180,  30]
                              : modalCloudCat === 'overcast'          ? [100, 110, 130]
                              : (dayHi !== null && dayHi < 9)         ? [ 60, 110, 180]
                              : modalCloudCat === 'scattered'         ? [160, 150, 130]
                              : modalCloudCat === 'wispy'             ? [200, 180, 130]
                              :                                         [220, 190,  50];
          const wBg  = weatherGradient(wR, wG, wB);
          const wBgActive = weatherGradientActive(wR, wG, wB);
          const wText = '#2a1d10';

          return html`
            <button
              key=${d.key}
              class=${`utci-day-tab ${isActive ? 'active' : ''}${locked ? ' locked' : ''}`}
              onClick=${() => {
                if (locked) {
                  setProPromptSource('day');
                  setProPromptDay(i);
                } else {
                  setSelectedDay(i);
                  setProPromptDay(null);
                }
              }}
              title=${locked
                ? `${band.label} · SunScope Extra unlocks day ${i + 1}`
                : `${band.label} · day ${i + 1} of 14`}
              style=${{
                background: isActive ? wBgActive : wBg,
                color: wText,
                border: '1px solid #c9b08a',
                opacity: locked ? 0.5 : 1,
                cursor: locked ? 'not-allowed' : 'pointer',
                position: 'relative',
                filter: isActive ? 'saturate(1.1) brightness(1.04)' : 'none',
              }}
            >
              <span style=${{
                position: 'absolute',
                bottom: 0,
                left: 0,
                right: 0,
                height: isActive ? '8px' : '7px',
                background: band.bg,
                borderTop: '1px solid #c9b08a',
                borderRadius: '0 0 2px 2px',
                transition: 'height 0.1s',
              }} aria-hidden="true"></span>
              ${locked && html`
                <span style=${{ position: 'absolute', top: '3px', right: '5px', fontSize: '10px', opacity: 0.75 }}>🔒</span>`}
              ${dayName}
              <span class="utci-day-date" style=${{ color: '#5a3f24' }}>
                ${dDate.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', timeZone: 'UTC' })}
              </span>
              <span style=${{ display: 'block', margin: '3px auto 0', lineHeight: 1 }}>
                ${showPrecip
                  ? html`<${PrecipIcon} precip=${dayPrecip} snow=${daySnow} size=${22} />`
                  : html`<${CloudIcon} category=${modalCloudCat} elev=${repElev} dt=${repDt} size=${22} />`}
              </span>
              ${dayHi !== null && html`
                <span style=${{
                  display: 'block',
                  fontFamily: 'Manrope, sans-serif',
                  fontStyle: 'normal',
                  fontSize: '13px',
                  marginTop: '2px',
                  letterSpacing: 0,
                  textTransform: 'none',
                  textShadow: '0 0 14px rgba(255,255,255,0.85), 0 0 11px rgba(255,255,255,0.7), 0 0 8px rgba(255,255,255,0.6), 0 0 5px rgba(255,255,255,0.5)',
                }}>
                  <span style=${{ color: '#c0622a', fontWeight: 800 }}>${dayHi}°</span>
                  <span style=${{ opacity: 0.5 }}> / </span>
                  <span style=${{ color: '#3a6080', fontWeight: 800 }}>${dayLo}°</span>
                </span>`}
            </button>`;
        })}
      </div>
      </div>

      ${proPromptDay !== null && days[proPromptDay] && (() => {
        const promptDate = new Date(days[proPromptDay].key + 'T00:00Z');
        const dayName    = promptDate.toLocaleDateString('en-GB', { weekday: 'long', timeZone: 'UTC' });
        const extraPromptCopy = {
          // Profile buttons
          'profile:alltemps': {
            title: 'Temps is part of SunScope Extra',
            detail: 'Extra unlocks the temperature comparison view — air, soil, concrete, vehicle interior, and indoor estimates side by side in one place.',
          },
          'profile:showall': {
            title: 'Show All is part of SunScope Extra',
            detail: 'Extra unlocks the full column set — every data point SunScope tracks, visible at once for deep-dive analysis.',
          },
          'profile:custom': {
            title: 'Custom columns are part of SunScope Extra',
            detail: 'Extra lets you hand-pick exactly which columns appear. Mix and match air, dew, soil, UV, UTCI and more to build your perfect view.',
          },
          // Places
          'variant:construction': {
            title: 'Construction is part of SunScope Extra',
            detail: 'Extra adds the Construction profile with felt temperature, wind, rain probability, visibility, and air quality — the key factors for safe site working.',
          },
          // Activities
          'variant:hiking': {
            title: 'Hiking is part of SunScope Extra',
            detail: 'Extra adds the Hiking profile with felt temperature, UV index, burn time, wind direction, and visibility — essential for longer days on exposed terrain.',
          },
          'variant:photography': {
            title: 'Photography is part of SunScope Extra',
            detail: 'Extra adds the Photography profile with direct and diffuse radiation, sun elevation, cloud cover, and visibility — the conditions that make or break a shoot.',
          },
          'variant:sailing': {
            title: 'Sailing is part of SunScope Extra',
            detail: 'Extra adds the Sailing profile with wind speed and direction, dew point, UV, burn time, sun elevation, and visibility for on-water planning.',
          },
          'variant:wintersports': {
            title: 'Winter Sports is part of SunScope Extra',
            detail: 'Extra adds the Winter Sports profile with UV-A and UV-B, burn time, sun elevation, wind direction, and visibility for snow and slope conditions.',
          },
          'variant:naturist': {
            title: 'Naturist is part of SunScope Extra',
            detail: 'Extra adds the Naturist profile with full skin-exposure detail — UV, burn time, felt temperature, dew point, humidity, and air quality.',
          },
          // Work
          'variant:market': {
            title: 'Market Trading is part of SunScope Extra',
            detail: 'Extra adds the Market Trading profile with felt temperature, wind direction, rain probability, and visibility — the key factors for planning stall days.',
          },
          'variant:windowcleaning': {
            title: 'Window Cleaning is part of SunScope Extra',
            detail: 'Extra adds the Window Cleaning profile focused on wind speed and direction, rain, and felt temperature — the conditions that determine whether work is safe and worthwhile.',
          },
          'variant:office': {
            title: 'Office is part of SunScope Extra',
            detail: 'Extra adds the Office profile with solar gain, managed indoor temperature, humidity, air quality, and rain probability — useful for commute planning and building comfort.',
          },
        };
        const promptCopy = extraPromptCopy[proPromptSource] || {
          title: `${dayName}'s forecast is part of SunScope Extra`,
          detail: 'Extra unlocks the full 14-day forecast, customisable columns, specialist profiles, and an ad-free view.',
        };
        return html`
          <div style=${{
            margin: '12px 0',
            padding: '18px 22px',
            background: '#fdf8ee',
            border: '1.5px solid #c9b08a',
            borderLeft: '4px solid #c8922a',
            borderRadius: '0 4px 4px 0',
            display: 'flex',
            flexWrap: 'wrap',
            alignItems: 'center',
            justifyContent: 'space-between',
            gap: '14px',
          }}>
            <div style=${{ flex: '1 1 320px', minWidth: '260px' }}>
              <div style=${{
                fontFamily: 'Fraunces, serif',
                fontStyle: 'italic',
                fontSize: '19px',
                fontWeight: 700,
                color: '#1e1208',
                marginBottom: '6px',
                lineHeight: 1.25,
              }}>
                <span style=${{ fontStyle: 'normal' }}>🔒</span> ${promptCopy.title}
              </div>
              <div style=${{
                fontFamily: 'Manrope, sans-serif',
                fontSize: '13.5px',
                color: '#4a3420',
                lineHeight: 1.65,
              }}>
                ${promptCopy.detail}
              </div>
              <div style=${{
                fontFamily: 'Manrope, sans-serif',
                fontWeight: 700,
                fontSize: '11px',
                textTransform: 'uppercase',
                letterSpacing: '0.07em',
                color: '#c8922a',
                marginTop: '10px',
              }}>
                £2 / month  ·  cancel any time
              </div>
            </div>
            <div style=${{
              display: 'flex',
              flexDirection: 'column',
              gap: '8px',
              alignItems: 'flex-end',
            }}>
              <a
                href="https://buy.stripe.com/9B63cw7vl8k15Ei9DQd7q00"
                target="_blank"
                rel="noopener noreferrer"
                style=${{
                  display: 'inline-block',
                  padding: '10px 18px',
                  background: '#c8922a',
                  color: '#fff',
                  textDecoration: 'none',
                  fontFamily: 'Manrope, sans-serif',
                  fontWeight: 700,
                  fontSize: '11px',
                  textTransform: 'uppercase',
                  letterSpacing: '0.07em',
                  borderRadius: '3px',
                  whiteSpace: 'nowrap',
                }}
              >
                Subscribe — £2/month
              </a>
              <a
                href="/restore.php"
                style=${{
                  fontFamily: 'Manrope, sans-serif',
                  fontWeight: 700,
                  fontSize: '10px',
                  textTransform: 'uppercase',
                  letterSpacing: '0.07em',
                  color: '#c8922a',
                  textDecoration: 'none',
                  borderBottom: '1px solid rgba(200,146,42,0.4)',
                  paddingBottom: '1px',
                }}
              >
                Already subscribed? Restore access →
              </a>
              <a
                href="https://billing.stripe.com/p/login/9B63cw7vl8k15Ei9DQd7q00"
                target="_blank"
                rel="noopener noreferrer"
                style=${{
                  fontFamily: 'Manrope, sans-serif',
                  fontWeight: 700,
                  fontSize: '10px',
                  textTransform: 'uppercase',
                  letterSpacing: '0.07em',
                  color: '#b09870',
                  textDecoration: 'none',
                  borderBottom: '1px solid rgba(176,152,112,0.4)',
                  paddingBottom: '1px',
                }}
              >
                Manage or cancel subscription →
              </a>
              <button
                onClick=${() => setProPromptDay(null)}
                style=${{
                  background: 'transparent',
                  border: 'none',
                  cursor: 'pointer',
                  fontFamily: 'Manrope, sans-serif',
                  fontWeight: 700,
                  fontSize: '10px',
                  textTransform: 'uppercase',
                  letterSpacing: '0.07em',
                  color: '#b09870',
                  padding: '2px 4px',
                }}
              >
                dismiss
              </button>
            </div>
          </div>`;
      })()}

      ${(() => {
        const band      = confidenceBand(selectedDay);
        const isOutlook = selectedDay >= 7;
        return html`
          <div style=${{
            display: 'flex',
            alignItems: 'center',
            gap: '10px',
            margin: '0 0 14px',
            padding: '6px 10px',
            background: band.tint,
            borderLeft: `3px solid ${band.edge}`,
            borderBottom: `1px solid ${band.edge}`,
            borderRadius: '0 4px 4px 0',
            fontSize: '12px',
            color: '#3a2a18',
            fontFamily: 'Manrope, sans-serif',
            fontWeight: 600,
            flexWrap: 'wrap',
          }}>
            <span style=${{ letterSpacing: '0.06em', textTransform: 'uppercase', fontWeight: 700 }}>
              Day ${selectedDay + 1} of 14 · Forecast clarity: ${band.label}
            </span>
            ${isOutlook && html`
              <span style=${{ opacity: 0.7, fontStyle: 'italic' }}>
                forecast skill is reduced — treat hourly detail as trend, not precision
              </span>`}
          </div>`;
      })()}


    </${Fragment}>`;
}
