Mercurial
comparison mrjunejune/src/tools/file_converter/index.html @ 258:60a876c4587a
[ui] Add semantic primitive ownership
Build a layered Zenbu token and sizing system, make authored controls use native-underneath primitives, migrate mrjunejune without imposing visual surfaces, and document/enforce HTML ownership in the catalog and wiki.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Wed, 05 Aug 2026 05:25:40 -0700 |
| parents | 3bdfffaad162 |
| children |
comparison
equal
deleted
inserted
replaced
| 257:609d3c6aff4e | 258:60a876c4587a |
|---|---|
| 7 {{/parts/base_head.html}} | 7 {{/parts/base_head.html}} |
| 8 <style> | 8 <style> |
| 9 .container { | 9 .container { |
| 10 max-width: 800px; | 10 max-width: 800px; |
| 11 margin: 2rem auto; | 11 margin: 2rem auto; |
| 12 padding: 2rem; | 12 padding: var(--zenbu-sys-padding-xl); |
| 13 } | 13 } |
| 14 | 14 |
| 15 .converter-section { | 15 .converter-section { |
| 16 border-radius: 8px; | 16 border-radius: var(--zenbu-sys-radius-control); |
| 17 border: 2px solid var(--lightgray); | 17 border: 2px solid var(--lightgray); |
| 18 padding: 2rem; | 18 padding: var(--zenbu-sys-padding-xl); |
| 19 margin-bottom: 2rem; | 19 margin-bottom: 2rem; |
| 20 } | 20 } |
| 21 | 21 |
| 22 .converter-section h2 { | 22 .converter-section h2 { |
| 23 margin-top: 0; | 23 margin-top: 0; |
| 33 margin-bottom: 0.5rem; | 33 margin-bottom: 0.5rem; |
| 34 font-weight: 600; | 34 font-weight: 600; |
| 35 } | 35 } |
| 36 | 36 |
| 37 input[type="file"] { | 37 input[type="file"] { |
| 38 padding: 0.75rem; | 38 padding: var(--zenbu-sys-padding-sm); |
| 39 border: 2px dashed #ccc; | 39 border: 2px dashed #ccc; |
| 40 border-radius: 4px; | 40 border-radius: var(--zenbu-sys-radius-control-small); |
| 41 background: white; | 41 background: white; |
| 42 font-size: 16px; | 42 font-size: var(--zenbu-sys-font-size-md); |
| 43 } | 43 } |
| 44 | 44 |
| 45 button { | 45 button { |
| 46 background: var(--purple); | 46 background: var(--purple); |
| 47 font-family: "More Thin", sans-serif; | 47 font-family: "More Thin", sans-serif; |
| 48 color: var(--gray-gradient); | 48 color: var(--gray-gradient); |
| 49 border: none; | 49 border: none; |
| 50 padding: 0.75rem 1.5rem; | 50 border-radius: var(--zenbu-sys-radius-control-small); |
| 51 border-radius: 4px; | |
| 52 cursor: pointer; | 51 cursor: pointer; |
| 53 font-size: 1rem; | |
| 54 margin-top: 1rem; | 52 margin-top: 1rem; |
| 55 min-height: 44px; | |
| 56 } | 53 } |
| 57 | 54 |
| 58 button:hover { | 55 button:hover { |
| 59 background: var(--orange); | 56 background: var(--orange); |
| 60 } | 57 } |
| 64 cursor: not-allowed; | 61 cursor: not-allowed; |
| 65 } | 62 } |
| 66 | 63 |
| 67 .result { | 64 .result { |
| 68 margin-top: 1rem; | 65 margin-top: 1rem; |
| 69 padding: 1rem; | 66 padding: var(--zenbu-sys-padding-md); |
| 70 background: white; | 67 background: white; |
| 71 border-radius: 4px; | 68 border-radius: var(--zenbu-sys-radius-control-small); |
| 72 display: none; | 69 display: none; |
| 73 } | 70 } |
| 74 | 71 |
| 75 .result.show { | 72 .result.show { |
| 76 display: block; | 73 display: block; |
| 105 } | 102 } |
| 106 | 103 |
| 107 /* Mobile responsive */ | 104 /* Mobile responsive */ |
| 108 @media (max-width: 720px) { | 105 @media (max-width: 720px) { |
| 109 .container { | 106 .container { |
| 110 padding: 1rem; | 107 padding: var(--zenbu-sys-padding-md); |
| 111 margin: 1rem auto; | 108 margin: 1rem auto; |
| 112 } | 109 } |
| 113 | 110 |
| 114 .converter-section { | 111 .converter-section { |
| 115 padding: 1.5rem 1rem; | 112 padding: |
| 113 var(--zenbu-sys-padding-lg) | |
| 114 var(--zenbu-sys-padding-md); | |
| 116 } | 115 } |
| 117 | 116 |
| 118 .converter-section h2 { | 117 .converter-section h2 { |
| 119 font-size: 1.5rem; | 118 font-size: var(--zenbu-sys-font-size-2xl); |
| 120 } | 119 } |
| 121 | 120 |
| 122 .file-input-wrapper label { | 121 .file-input-wrapper label { |
| 123 font-size: 1rem; | 122 font-size: var(--zenbu-sys-font-size-md); |
| 124 } | 123 } |
| 125 | 124 |
| 126 button { | |
| 127 font-size: 1.1rem; | |
| 128 padding: 1rem 1.5rem; | |
| 129 } | |
| 130 | 125 |
| 131 .result { | 126 .result { |
| 132 padding: 1rem; | 127 padding: var(--zenbu-sys-padding-md); |
| 133 font-size: 1rem; | 128 font-size: var(--zenbu-sys-font-size-md); |
| 134 } | 129 } |
| 135 } | 130 } |
| 136 </style> | 131 </style> |
| 137 </head> | 132 </head> |
| 138 <body> | 133 <body> |
| 146 <h2>Image to WebP Converter</h2> | 141 <h2>Image to WebP Converter</h2> |
| 147 <p>Upload an image file (PNG, JPG, GIF, etc.) to convert it to WebP format</p> | 142 <p>Upload an image file (PNG, JPG, GIF, etc.) to convert it to WebP format</p> |
| 148 | 143 |
| 149 <div class="file-input-wrapper"> | 144 <div class="file-input-wrapper"> |
| 150 <label for="imageInput">Choose an image file:</label> | 145 <label for="imageInput">Choose an image file:</label> |
| 151 <input type="file" id="imageInput" accept="image/*"> | 146 <zen-input appearance="plain" size="md"> |
| 147 <input type="file" id="imageInput" accept="image/*"> | |
| 148 </zen-input> | |
| 152 </div> | 149 </div> |
| 153 | 150 |
| 154 <button id="convertImageBtn" onclick="convertImageToWebP()">Convert to WebP</button> | 151 <zen-button appearance="plain" size="md"> |
| 152 <button id="convertImageBtn" onclick="convertImageToWebP()">Convert to WebP</button> | |
| 153 </zen-button> | |
| 155 | 154 |
| 156 <div class="loading" id="imageLoading">Converting... Please wait.</div> | 155 <div class="loading" id="imageLoading">Converting... Please wait.</div> |
| 157 | 156 |
| 158 <div class="result" id="imageResult"> | 157 <div class="result" id="imageResult"> |
| 159 <p id="imageMessage"></p> | 158 <p id="imageMessage"></p> |
| 165 <h2>Video to MP4 Converter</h2> | 164 <h2>Video to MP4 Converter</h2> |
| 166 <p>Upload a video file (AVI, MOV, MKV, etc.) to convert it to MP4 format</p> | 165 <p>Upload a video file (AVI, MOV, MKV, etc.) to convert it to MP4 format</p> |
| 167 | 166 |
| 168 <div class="file-input-wrapper"> | 167 <div class="file-input-wrapper"> |
| 169 <label for="videoInput">Choose a video file:</label> | 168 <label for="videoInput">Choose a video file:</label> |
| 170 <input type="file" id="videoInput" accept="video/*"> | 169 <zen-input appearance="plain" size="md"> |
| 170 <input type="file" id="videoInput" accept="video/*"> | |
| 171 </zen-input> | |
| 171 </div> | 172 </div> |
| 172 | 173 |
| 173 <button id="convertVideoBtn" onclick="convertVideoToMP4()">Convert to MP4</button> | 174 <zen-button appearance="plain" size="md"> |
| 175 <button id="convertVideoBtn" onclick="convertVideoToMP4()">Convert to MP4</button> | |
| 176 </zen-button> | |
| 174 | 177 |
| 175 <div class="loading" id="videoLoading">Converting... Please wait.</div> | 178 <div class="loading" id="videoLoading">Converting... Please wait.</div> |
| 176 | 179 |
| 177 <div class="result" id="videoResult"> | 180 <div class="result" id="videoResult"> |
| 178 <p id="videoMessage"></p> | 181 <p id="videoMessage"></p> |