feat(pwa): installable app — manifest + SW + Settings install button
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
The captive-portal Step-2 QR opens pictureframe.edholm.me in Safari, which is the perfect moment to also offer "pin this to your home screen" so the recipient gets one-tap access without typing the URL again. Two pieces: * Service worker at /sw.js (document root, scope "/"). Minimal — install/activate calls skipWaiting + clients.claim, fetch is passthrough. Real offline caching is intentionally out of scope; we only need the SW to exist so Chrome's PWA-install heuristic fires. * Settings → Install app section, hidden when display-mode standalone. Android Chrome path: native beforeinstallprompt button. iOS Safari (and any other non-prompt browser): button opens a modal with step-by-step Share → Add to Home Screen instructions. usePwaInstall composable handles the singleton lifecycle — beforeinstallprompt fires once per page load and may fire before the user navigates to Settings, so we register on module import and stash the event for later. Tests cover: install button rendered when not standalone, modal opens on click without a native prompt, modal close button works. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{J as e,M as t,P as n,S as r,_ as i,b as a,g as o,h as s,p as c,t as l,x as u,y as d,z as f}from"./_plugin-vue_export-helper-eepT72yB.js";import{n as p,t as m}from"./BaseBottomSheet-BMI-Oljh.js";var h={class:`device-picker__list`},g=[`checked`,`onChange`],_={class:`device-picker__name`},v={class:`device-picker__orientation`},y=l(r({__name:`DevicePicker`,props:{modelValue:{type:Boolean},devices:{},selected:{},uploading:{type:Boolean}},emits:[`update:modelValue`,`update:selected`,`confirm`],setup(r,{emit:l}){let y=r,b=l;function x(e){y.selected.includes(e)?b(`update:selected`,y.selected.filter(t=>t!==e)):b(`update:selected`,[...y.selected,e])}let S=s(()=>{let e=y.selected.length;return e===0?`Add to frame`:`Add to ${e} frame${e>1?`s`:``}`});return(s,l)=>(t(),i(m,{"model-value":r.modelValue,label:`Choose frames`,"onUpdate:modelValue":l[1]||=e=>s.$emit(`update:modelValue`,e)},{default:f(()=>[l[2]||=o(`h2`,{class:`device-picker__title`},`Add to frames`,-1),l[3]||=o(`p`,{class:`device-picker__sub`},`Choose which frames will show this photo.`,-1),o(`div`,h,[(t(!0),d(c,null,n(r.devices,n=>(t(),d(`label`,{key:n.id,class:`device-picker__row`},[o(`input`,{type:`checkbox`,class:`device-picker__check`,checked:r.selected.includes(n.id),onChange:e=>x(n.id)},null,40,g),o(`span`,_,e(n.name),1),o(`span`,v,e(n.orientation),1)]))),128))]),u(p,{variant:`primary`,class:`device-picker__confirm`,disabled:r.selected.length===0||r.uploading,onClick:l[0]||=e=>s.$emit(`confirm`)},{default:f(()=>[a(e(r.uploading?`Uploading…`:S.value),1)]),_:1},8,[`disabled`])]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-a6466fa5`]]);export{y as t};
|
||||
@@ -1 +0,0 @@
|
||||
import{_ as e,d as t,f as n,g as r,j as i,k as a,m as o,pt as s,s as c,t as l,u,v as d,z as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,t as m}from"./BaseBottomSheet-D5oDq9XR.js";var h={class:`device-picker__list`},g=[`checked`,`onChange`],_={class:`device-picker__name`},v={class:`device-picker__orientation`},y=l(d({__name:`DevicePicker`,props:{modelValue:{type:Boolean},devices:{},selected:{},uploading:{type:Boolean}},emits:[`update:modelValue`,`update:selected`,`confirm`],setup(l,{emit:d}){let y=l,b=d;function x(e){y.selected.includes(e)?b(`update:selected`,y.selected.filter(t=>t!==e)):b(`update:selected`,[...y.selected,e])}let S=u(()=>{let e=y.selected.length;return e===0?`Add to frame`:`Add to ${e} frame${e>1?`s`:``}`});return(u,d)=>(a(),n(m,{"model-value":l.modelValue,label:`Choose frames`,"onUpdate:modelValue":d[1]||=e=>u.$emit(`update:modelValue`,e)},{default:f(()=>[d[2]||=t(`h2`,{class:`device-picker__title`},`Add to frames`,-1),d[3]||=t(`p`,{class:`device-picker__sub`},`Choose which frames will show this photo.`,-1),t(`div`,h,[(a(!0),o(c,null,i(l.devices,e=>(a(),o(`label`,{key:e.id,class:`device-picker__row`},[t(`input`,{type:`checkbox`,class:`device-picker__check`,checked:l.selected.includes(e.id),onChange:t=>x(e.id)},null,40,g),t(`span`,_,s(e.name),1),t(`span`,v,s(e.orientation),1)]))),128))]),e(p,{variant:`primary`,class:`device-picker__confirm`,disabled:l.selected.length===0||l.uploading,onClick:d[0]||=e=>u.$emit(`confirm`)},{default:f(()=>[r(s(l.uploading?`Uploading…`:S.value),1)]),_:1},8,[`disabled`])]),_:1},8,[`model-value`]))}}),[[`__scopeId`,`data-v-a6466fa5`]]);export{y as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{F as e,H as t,K as n,M as r,S as i,g as a,h as o,q as s,t as c,y as l}from"./_plugin-vue_export-helper-eepT72yB.js";var u={key:1,class:`ptr__spinner`,role:`status`,"aria-label":`Refreshing`},d=c(i({__name:`PullToRefresh`,props:{isAtTop:{},onRefresh:{},threshold:{default:80},maxPull:{default:140}},setup(i){let c=i,d=t(0),f=t(!1),p=0,m=0,h=!1,g=null,_=o(()=>Math.min(d.value/c.threshold,1)),v=o(()=>f.value?1:Math.min(d.value/c.threshold,1)),y=o(()=>({transform:`translateY(${d.value}px)`,transition:h?`none`:`transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1)`}));function b(e){f.value||c.isAtTop&&!c.isAtTop()||e.touches.length===1&&(p=e.touches[0].clientY,m=e.touches[0].clientX,h=!0,g=null)}function x(e){if(!h)return;let t=e.touches[0].clientX-m,n=e.touches[0].clientY-p;if(g===null){if(Math.abs(t)<6&&Math.abs(n)<6)return;g=Math.abs(t)>Math.abs(n)?`x`:`y`}if(g===`x`||n<=0){h=!1,d.value=0;return}if(c.isAtTop&&!c.isAtTop()){h=!1,d.value=0;return}let r=n<c.maxPull?n*.5:c.maxPull*.5+(n-c.maxPull)*.1;d.value=Math.min(r,c.maxPull*.7),e.cancelable&&e.preventDefault()}async function S(){if(h)if(h=!1,d.value>=c.threshold){f.value=!0,d.value=c.threshold*.7;try{await c.onRefresh()}catch(e){console.error(`Pull-to-refresh failed:`,e)}finally{f.value=!1,d.value=0}}else d.value=0}return(t,i)=>(r(),l(`div`,{class:`ptr`,onTouchstartPassive:b,onTouchmove:x,onTouchend:S,onTouchcancel:S},[a(`div`,{class:n([`ptr__indicator`,{"ptr__indicator--ready":_.value>=1}]),style:s({opacity:v.value,transform:`translateY(${d.value*.6}px)`}),"aria-hidden":`true`},[f.value?(r(),l(`div`,u)):(r(),l(`svg`,{key:0,class:`ptr__arrow`,viewBox:`0 0 24 24`,style:s({transform:`rotate(${_.value*180}deg)`})},[...i[0]||=[a(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`,stroke:`currentColor`,"stroke-width":`2.5`,"stroke-linecap":`round`},null,-1),a(`polyline`,{points:`6 13 12 19 18 13`,stroke:`currentColor`,"stroke-width":`2.5`,fill:`none`,"stroke-linecap":`round`,"stroke-linejoin":`round`},null,-1)]],4))],6),a(`div`,{class:`ptr__content`,style:s(y.value)},[e(t.$slots,`default`,{},void 0,!0)],4)],32))}}),[[`__scopeId`,`data-v-e2242f3c`]]);export{d as t};
|
||||
@@ -1 +0,0 @@
|
||||
import{H as e,M as t,d as n,dt as r,ft as i,k as a,m as o,t as s,u as c,v as l}from"./_plugin-vue_export-helper-DRLwVS0w.js";var u={key:1,class:`ptr__spinner`,role:`status`,"aria-label":`Refreshing`},d=s(l({__name:`PullToRefresh`,props:{isAtTop:{},onRefresh:{},threshold:{default:80},maxPull:{default:140}},setup(s){let l=s,d=e(0),f=e(!1),p=0,m=0,h=!1,g=null,_=c(()=>Math.min(d.value/l.threshold,1)),v=c(()=>f.value?1:Math.min(d.value/l.threshold,1)),y=c(()=>({transform:`translateY(${d.value}px)`,transition:h?`none`:`transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1)`}));function b(e){f.value||l.isAtTop&&!l.isAtTop()||e.touches.length===1&&(p=e.touches[0].clientY,m=e.touches[0].clientX,h=!0,g=null)}function x(e){if(!h)return;let t=e.touches[0].clientX-m,n=e.touches[0].clientY-p;if(g===null){if(Math.abs(t)<6&&Math.abs(n)<6)return;g=Math.abs(t)>Math.abs(n)?`x`:`y`}if(g===`x`||n<=0){h=!1,d.value=0;return}if(l.isAtTop&&!l.isAtTop()){h=!1,d.value=0;return}let r=n<l.maxPull?n*.5:l.maxPull*.5+(n-l.maxPull)*.1;d.value=Math.min(r,l.maxPull*.7),e.cancelable&&e.preventDefault()}async function S(){if(h)if(h=!1,d.value>=l.threshold){f.value=!0,d.value=l.threshold*.7;try{await l.onRefresh()}catch(e){console.error(`Pull-to-refresh failed:`,e)}finally{f.value=!1,d.value=0}}else d.value=0}return(e,s)=>(a(),o(`div`,{class:`ptr`,onTouchstartPassive:b,onTouchmove:x,onTouchend:S,onTouchcancel:S},[n(`div`,{class:r([`ptr__indicator`,{"ptr__indicator--ready":_.value>=1}]),style:i({opacity:v.value,transform:`translateY(${d.value*.6}px)`}),"aria-hidden":`true`},[f.value?(a(),o(`div`,u)):(a(),o(`svg`,{key:0,class:`ptr__arrow`,viewBox:`0 0 24 24`,style:i({transform:`rotate(${_.value*180}deg)`})},[...s[0]||=[n(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`,stroke:`currentColor`,"stroke-width":`2.5`,"stroke-linecap":`round`},null,-1),n(`polyline`,{points:`6 13 12 19 18 13`,stroke:`currentColor`,"stroke-width":`2.5`,fill:`none`,"stroke-linecap":`round`,"stroke-linejoin":`round`},null,-1)]],4))],6),n(`div`,{class:`ptr__content`,style:i(y.value)},[t(e.$slots,`default`,{},void 0,!0)],4)],32))}}),[[`__scopeId`,`data-v-e2242f3c`]]);export{d as t};
|
||||
@@ -1 +0,0 @@
|
||||
import{K as e,d as t,dt as n,ft as r,j as i,k as a,m as o,p as s,pt as c,s as l,t as u,u as d,v as f}from"./_plugin-vue_export-helper-DRLwVS0w.js";import{n as p,r as m,t as h}from"./index-CCy85pot.js";var g={class:`settings`},_={class:`settings__section`},v={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},y=[`aria-checked`,`aria-label`,`onClick`],b={class:`theme-swatch__label`},x={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},S={class:`settings__section`},C={class:`settings__row`},w={class:`settings__row-value`},T=u(f({__name:`SettingsView`,setup(u){let f=m(),{saveTheme:T}=p(),E=d(()=>f.user?.theme??`warm-craft`);function D(e){T(e)}return(u,d)=>(a(),o(`main`,g,[d[5]||=t(`h1`,{class:`settings__title`},`Settings`,-1),t(`section`,_,[d[1]||=t(`h2`,{class:`settings__section-title`},`Theme`,-1),t(`div`,v,[(a(!0),o(l,null,i(e(h),e=>(a(),o(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":E.value===e.id,"aria-label":e.label,class:n([`theme-swatch`,{"theme-swatch--active":E.value===e.id}]),style:r({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>D(e.id)},[d[0]||=t(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[t(`span`,{class:`theme-swatch__bar`}),t(`span`,{class:`theme-swatch__dot`})],-1),t(`span`,b,c(e.label),1),E.value===e.id?(a(),o(`span`,x,`✓`)):s(``,!0)],14,y))),128))])]),t(`section`,S,[d[3]||=t(`h2`,{class:`settings__section-title`},`Account`,-1),t(`div`,C,[d[2]||=t(`span`,{class:`settings__row-label`},`Signed in as`,-1),t(`span`,w,c(e(f).user?.email),1)]),d[4]||=t(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)])]))}}),[[`__scopeId`,`data-v-76ec3881`]]);export{T as default};
|
||||
@@ -1 +0,0 @@
|
||||
.settings[data-v-76ec3881]{padding:var(--space-4) var(--space-4) calc(var(--bottom-nav-height) + var(--space-6));max-width:480px;margin:0 auto}.settings__title[data-v-76ec3881]{font-size:var(--text-xl);margin-bottom:var(--space-6);font-weight:700}.settings__section[data-v-76ec3881]{margin-bottom:var(--space-6)}.settings__section-title[data-v-76ec3881]{font-size:var(--text-sm);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--space-3);font-weight:700}.settings__row[data-v-76ec3881]{padding:var(--space-3) 0;border-bottom:1px solid var(--color-border);font-size:var(--text-base);justify-content:space-between;align-items:center;display:flex}.settings__row-label[data-v-76ec3881]{color:var(--color-text-muted)}.settings__row-value[data-v-76ec3881]{font-weight:600}.settings__logout[data-v-76ec3881]{min-height:var(--touch-min);padding:var(--space-3) 0;color:var(--color-destructive);font-weight:600;font-size:var(--text-base);align-items:center;text-decoration:none;display:flex}.theme-grid[data-v-76ec3881]{gap:var(--space-3);grid-template-columns:repeat(3,1fr);display:grid}.theme-swatch[data-v-76ec3881]{align-items:center;gap:var(--space-2);padding:var(--space-3);background:var(--swatch-bg);border-radius:var(--radius-md);cursor:pointer;transition:border-color var(--duration-fast);min-height:var(--touch-min);border:2px solid #0000;flex-direction:column;display:flex;position:relative}.theme-swatch--active[data-v-76ec3881]{border-color:var(--swatch-primary)}.theme-swatch__preview[data-v-76ec3881]{border-radius:var(--radius-sm);background:var(--swatch-bg);border:1px solid color-mix(in srgb, var(--swatch-text) 15%, transparent);flex-direction:column;justify-content:center;gap:4px;width:100%;height:36px;padding:0 6px;display:flex}.theme-swatch__bar[data-v-76ec3881]{background:var(--swatch-primary);border-radius:3px;width:60%;height:6px;display:block}.theme-swatch__dot[data-v-76ec3881]{background:var(--swatch-text);opacity:.4;border-radius:2px;width:80%;height:4px;display:block}.theme-swatch__label[data-v-76ec3881]{font-size:var(--text-xs);color:var(--color-text);text-align:center;font-weight:600;line-height:1.2}.theme-swatch__check[data-v-76ec3881]{top:var(--space-1);right:var(--space-2);font-size:var(--text-sm);color:var(--swatch-primary);font-weight:700;position:absolute}
|
||||
@@ -0,0 +1 @@
|
||||
import{G as e,H as t,J as n,K as r,M as i,P as a,S as o,b as s,f as c,g as l,h as u,p as d,q as f,t as p,v as m,y as h}from"./_plugin-vue_export-helper-eepT72yB.js";import{n as g,r as _,t as v}from"./index-BO5caB_f.js";var y=t(null),b=t(!1);function x(){return typeof window>`u`?!1:window.matchMedia?.(`(display-mode: standalone)`).matches?!0:window.navigator.standalone===!0}function S(){if(typeof navigator>`u`)return!1;let e=navigator.userAgent,t=e.includes(`Mac`)&&navigator.maxTouchPoints>1;return/iPhone|iPod/.test(e)||t}var C=!1;function w(){C||typeof window>`u`||(C=!0,b.value=x(),window.addEventListener(`beforeinstallprompt`,e=>{e.preventDefault(),y.value=e}),window.addEventListener(`appinstalled`,()=>{y.value=null,b.value=!0}),window.matchMedia?.(`(display-mode: standalone)`).addEventListener(`change`,e=>{b.value=e.matches}))}w();function T(){let e=S(),t=u(()=>y.value!==null);async function n(){let e=y.value;if(!e)return!1;await e.prompt();let t=await e.userChoice;return y.value=null,t.outcome===`accepted`}return{isStandalone:b,isIOS:e,canPromptInstall:t,install:n}}var E={class:`settings`},D={key:0,class:`settings__section`},O={class:`settings__section`},k={class:`theme-grid`,role:`radiogroup`,"aria-label":`Choose theme`},A=[`aria-checked`,`aria-label`,`onClick`],j={class:`theme-swatch__label`},M={key:0,class:`theme-swatch__check`,"aria-hidden":`true`},N={class:`settings__section`},P={class:`settings__row`},F={class:`settings__row-value`},I={class:`install-modal__card`},L={id:`install-modal-title`,class:`install-modal__title`},R={class:`install-modal__steps`},z={key:0},B={key:1},V={key:0},H=p(o({__name:`SettingsView`,setup(o){let p=_(),{saveTheme:y}=g(),{isStandalone:b,isIOS:x,canPromptInstall:S,install:C}=T(),w=u(()=>p.user?.theme??`warm-craft`),H=t(!1);function U(e){y(e)}async function W(){!await C()&&!S.value&&(H.value=!0)}return(t,o)=>(i(),h(`main`,E,[o[18]||=l(`h1`,{class:`settings__title`},`Settings`,-1),e(b)?m(``,!0):(i(),h(`section`,D,[o[3]||=l(`h2`,{class:`settings__section-title`},`Install app`,-1),o[4]||=l(`p`,{class:`settings__hint`},` Pin pictureFrame to your home screen so it opens like a native app. `,-1),e(S)?(i(),h(`button`,{key:0,type:`button`,class:`settings__install`,onClick:W},` Install pictureFrame `)):(i(),h(`button`,{key:1,type:`button`,class:`settings__install`,onClick:o[0]||=e=>H.value=!0},` Add to Home Screen `))])),l(`section`,O,[o[6]||=l(`h2`,{class:`settings__section-title`},`Theme`,-1),l(`div`,k,[(i(!0),h(d,null,a(e(v),e=>(i(),h(`button`,{key:e.id,type:`button`,role:`radio`,"aria-checked":w.value===e.id,"aria-label":e.label,class:r([`theme-swatch`,{"theme-swatch--active":w.value===e.id}]),style:f({"--swatch-bg":e.bg,"--swatch-primary":e.primary,"--swatch-text":e.text}),onClick:t=>U(e.id)},[o[5]||=l(`span`,{class:`theme-swatch__preview`,"aria-hidden":`true`},[l(`span`,{class:`theme-swatch__bar`}),l(`span`,{class:`theme-swatch__dot`})],-1),l(`span`,j,n(e.label),1),w.value===e.id?(i(),h(`span`,M,`✓`)):m(``,!0)],14,A))),128))])]),l(`section`,N,[o[8]||=l(`h2`,{class:`settings__section-title`},`Account`,-1),l(`div`,P,[o[7]||=l(`span`,{class:`settings__row-label`},`Signed in as`,-1),l(`span`,F,n(e(p).user?.email),1)]),o[9]||=l(`a`,{href:`/logout`,class:`settings__logout`},`Sign out`,-1)]),H.value?(i(),h(`div`,{key:1,class:`install-modal`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`install-modal-title`,onClick:o[2]||=c(e=>H.value=!1,[`self`])},[l(`div`,I,[l(`button`,{type:`button`,class:`install-modal__close`,"aria-label":`Close`,onClick:o[1]||=e=>H.value=!1},`×`),l(`h2`,L,n(e(x)?`Add to your iPhone home screen`:`Add to your home screen`),1),l(`ol`,R,[e(x)?(i(),h(`li`,z,[...o[10]||=[s(` Tap the `,-1),l(`strong`,null,`Share`,-1),s(` icon at the bottom of Safari (the square with an up-arrow). `,-1)]])):(i(),h(`li`,B,[...o[11]||=[s(` Open your browser's menu (usually the three dots `,-1),l(`strong`,null,`⋮`,-1),s(` in the top right). `,-1)]])),l(`li`,null,[o[13]||=s(` Scroll down and tap `,-1),o[14]||=l(`strong`,null,`Add to Home Screen`,-1),e(x)?m(``,!0):(i(),h(`span`,V,[...o[12]||=[s(`or `,-1),l(`strong`,null,`Install app`,-1)]])),o[15]||=s(`. `,-1)]),o[16]||=l(`li`,null,[s(` Tap `),l(`strong`,null,`Add`),s(` in the top right to confirm. `)],-1)]),o[17]||=l(`p`,{class:`install-modal__footer`},` The app will appear on your home screen and open without browser chrome the next time you launch it. `,-1)])])):m(``,!0)]))}}),[[`__scopeId`,`data-v-6f8a8b72`]]);export{H as default};
|
||||
@@ -0,0 +1 @@
|
||||
.settings[data-v-6f8a8b72]{padding:var(--space-4) var(--space-4) calc(var(--bottom-nav-height) + var(--space-6));max-width:480px;margin:0 auto}.settings__title[data-v-6f8a8b72]{font-size:var(--text-xl);margin-bottom:var(--space-6);font-weight:700}.settings__section[data-v-6f8a8b72]{margin-bottom:var(--space-6)}.settings__section-title[data-v-6f8a8b72]{font-size:var(--text-sm);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.06em;margin-bottom:var(--space-3);font-weight:700}.settings__row[data-v-6f8a8b72]{padding:var(--space-3) 0;border-bottom:1px solid var(--color-border);font-size:var(--text-base);justify-content:space-between;align-items:center;display:flex}.settings__row-label[data-v-6f8a8b72]{color:var(--color-text-muted)}.settings__row-value[data-v-6f8a8b72]{font-weight:600}.settings__logout[data-v-6f8a8b72]{min-height:var(--touch-min);padding:var(--space-3) 0;color:var(--color-destructive);font-weight:600;font-size:var(--text-base);align-items:center;text-decoration:none;display:flex}.settings__hint[data-v-6f8a8b72]{color:var(--color-text-muted);font-size:var(--text-sm);margin-bottom:var(--space-3);line-height:1.4}.settings__install[data-v-6f8a8b72]{width:100%;min-height:var(--touch-min);background:var(--color-primary);color:var(--color-on-primary);border-radius:var(--radius-pill,9999px);font-size:var(--text-base);cursor:pointer;border:none;justify-content:center;align-items:center;font-weight:700;display:flex}.install-modal[data-v-6f8a8b72]{padding:var(--space-4);z-index:100;background:#00000080;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.install-modal__card[data-v-6f8a8b72]{background:var(--color-surface);color:var(--color-text);border-radius:var(--radius-lg,16px);padding:var(--space-5);width:100%;max-width:380px;position:relative;box-shadow:0 20px 60px #00000040}.install-modal__close[data-v-6f8a8b72]{top:var(--space-2);right:var(--space-3);color:var(--color-text-muted);cursor:pointer;padding:var(--space-1) var(--space-2);background:0 0;border:none;font-size:1.75rem;line-height:1;position:absolute}.install-modal__title[data-v-6f8a8b72]{font-size:var(--text-lg);margin-bottom:var(--space-3);padding-right:var(--space-5);font-weight:700}.install-modal__steps[data-v-6f8a8b72]{margin:0 0 var(--space-3) var(--space-4);padding:0;line-height:1.5}.install-modal__steps li[data-v-6f8a8b72]{margin-bottom:var(--space-2)}.install-modal__footer[data-v-6f8a8b72]{color:var(--color-text-muted);font-size:var(--text-sm);margin-top:var(--space-3);border-top:1px solid var(--color-border);padding-top:var(--space-3);line-height:1.4}.theme-grid[data-v-6f8a8b72]{gap:var(--space-3);grid-template-columns:repeat(3,1fr);display:grid}.theme-swatch[data-v-6f8a8b72]{align-items:center;gap:var(--space-2);padding:var(--space-3);background:var(--swatch-bg);border-radius:var(--radius-md);cursor:pointer;transition:border-color var(--duration-fast);min-height:var(--touch-min);border:2px solid #0000;flex-direction:column;display:flex;position:relative}.theme-swatch--active[data-v-6f8a8b72]{border-color:var(--swatch-primary)}.theme-swatch__preview[data-v-6f8a8b72]{border-radius:var(--radius-sm);background:var(--swatch-bg);border:1px solid color-mix(in srgb, var(--swatch-text) 15%, transparent);flex-direction:column;justify-content:center;gap:4px;width:100%;height:36px;padding:0 6px;display:flex}.theme-swatch__bar[data-v-6f8a8b72]{background:var(--swatch-primary);border-radius:3px;width:60%;height:6px;display:block}.theme-swatch__dot[data-v-6f8a8b72]{background:var(--swatch-text);opacity:.4;border-radius:2px;width:80%;height:4px;display:block}.theme-swatch__label[data-v-6f8a8b72]{font-size:var(--text-xs);color:var(--color-text);text-align:center;font-weight:600;line-height:1.2}.theme-swatch__check[data-v-6f8a8b72]{top:var(--space-1);right:var(--space-2);font-size:var(--text-sm);color:var(--swatch-primary);font-weight:700;position:absolute}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -14,8 +14,8 @@
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content="pictureFrame" />
|
||||
<script type="module" crossorigin src="/build/assets/index-CCy85pot.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/build/assets/_plugin-vue_export-helper-DRLwVS0w.js">
|
||||
<script type="module" crossorigin src="/build/assets/index-BO5caB_f.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/build/assets/_plugin-vue_export-helper-eepT72yB.js">
|
||||
<link rel="stylesheet" crossorigin href="/build/assets/index-BlLBHR1q.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user