/
home
/
learningaswinslo
/
public_html
/
HSEQ Voice Transcriber
/
/home/learningaswinslo/public_html/HSEQ Voice Transcriber
mkdir
upload
Name
Size
Mode
Actions
index.html
41808
0644
edit
dl
rm
README.txt
3737
0644
edit
dl
rm
winslow-logo.png
140219
0644
edit
dl
rm
Edit:
/home/learningaswinslo/public_html/HSEQ Voice Transcriber/index.html
(41808B)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Winslow HSEQ Transcriber — Record · Transcribe · Send</title> <style> /* Winslow digital typefaces: Oswald for headings/labels, Archivo Narrow for body copy. */ @import url('https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;600;700&family=Archivo+Narrow:wght@400;500;600;700&display=swap'); :root { /* Winslow brand palette */ --navy: #000000; /* Winslow Black */ --navy-darker: #1a1a1a; /* black hover / pressed */ --yellow: #EAAB00; /* Winslow Yellow (PMS 124 C) */ --yellow-deep: #C8920A; /* darker yellow for active mic */ --gray-9: #888B95; /* Winslow Grey (Cool Gray 8 C) */ --gray-4: #B8B9BF; /* Winslow Grey 60% tint */ --dusk: #D9E1F2; /* Winslow Grey Dusk */ --ink: #1a1a1a; --paper: #ffffff; --panel: #f4f6fb; /* very light dusk wash */ --line: #DBDCDF; /* Winslow Grey 30% tint */ --shadow: 0 20px 50px rgba(0, 0, 0, 0.16); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Archivo Narrow', sans-serif; background: radial-gradient(900px 500px at 85% -5%, rgba(234,171,0,0.12), transparent 60%), radial-gradient(1000px 600px at 0% 100%, rgba(217,225,242,0.55), transparent 55%), #eef1f5; color: var(--ink); min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: clamp(0px, 3vw, 28px); -webkit-text-size-adjust: 100%; } .app { width: 100%; max-width: 660px; background: var(--paper); border-radius: clamp(0px, 2.5vw, 20px); box-shadow: var(--shadow); overflow: hidden; border: 1px solid var(--line); } /* ---- Header with brand bar ---- */ header { background: var(--paper); padding: clamp(16px, 4vw, 22px) clamp(18px, 5vw, 32px); display: flex; align-items: center; justify-content: space-between; gap: 12px; position: relative; overflow: hidden; border-bottom: 3px solid var(--yellow); } .logo { display: flex; align-items: center; z-index: 2; min-width: 0; height: clamp(40px, 11vw, 54px); } .logo img { height: 100%; width: auto; max-width: min(62vw, 360px); object-fit: contain; object-position: left center; display: block; } .header-right { display: flex; align-items: center; gap: clamp(8px, 2.5vw, 14px); z-index: 2; } .gear { background: var(--panel); border: 1px solid var(--line); color: var(--navy); width: 44px; height: 44px; border-radius: 10px; cursor: pointer; display: grid; place-items: center; transition: all 0.2s ease; flex-shrink: 0; } .gear:hover { background: var(--yellow); color: var(--navy); border-color: var(--yellow); transform: rotate(40deg); } .gear svg { width: 18px; height: 18px; } .app-title { background: var(--navy); color: #fff; font-family: 'Oswald', sans-serif; font-weight: 600; font-size: clamp(20px, 5.5vw, 28px); letter-spacing: 2px; text-transform: uppercase; text-align: center; padding: clamp(12px, 3.5vw, 16px) clamp(18px, 5vw, 32px); line-height: 1.1; } .stage { padding: clamp(22px, 6vw, 36px) clamp(18px, 5vw, 32px) clamp(20px, 5vw, 30px); display: flex; flex-direction: column; align-items: center; gap: clamp(16px, 4vw, 20px); } /* ---- Mic ---- */ .mic-wrap { position: relative; width: clamp(120px, 36vw, 140px); height: clamp(120px, 36vw, 140px); display: grid; place-items: center; } .pulse { position: absolute; inset: 0; border-radius: 50%; background: rgba(0,0,0,0.12); transform: scale(0.6); opacity: 0; } .recording .pulse { animation: pulse 1.6s ease-out infinite; background: rgba(234,171,0,0.35); } @keyframes pulse { 0% { transform: scale(0.7); opacity: 0.75; } 100% { transform: scale(1.65); opacity: 0; } } .mic { width: clamp(86px, 26vw, 100px); height: clamp(86px, 26vw, 100px); border-radius: 50%; border: none; cursor: pointer; background: linear-gradient(150deg, #2a2a2a, var(--navy)); color: #fff; display: grid; place-items: center; box-shadow: 0 12px 30px rgba(0,0,0,0.4); transition: transform 0.15s ease, box-shadow 0.3s ease; position: relative; z-index: 2; } .mic:hover { transform: translateY(-2px); } .mic:active { transform: scale(0.96); } .recording .mic { background: linear-gradient(150deg, var(--yellow), var(--yellow-deep)); color: var(--navy); box-shadow: 0 0 0 5px rgba(234,171,0,0.25); } .mic svg { width: clamp(34px, 10vw, 40px); height: clamp(34px, 10vw, 40px); } .timer { font-family: 'Oswald', sans-serif; font-size: clamp(28px, 8vw, 34px); font-weight: 600; color: var(--navy); font-variant-numeric: tabular-nums; letter-spacing: 1px; } .status { font-family: 'Oswald', sans-serif; font-size: 12px; font-weight: 500; letter-spacing: 1.5px; text-transform: uppercase; color: var(--gray-9); min-height: 16px; text-align: center; } .status.live { color: var(--navy); } .status.live::before { content: "● "; color: #d11; } .record-toggle { display: inline-flex; align-items: center; justify-content: center; gap: 10px; padding: 14px clamp(22px, 6vw, 26px); border-radius: 40px; cursor: pointer; font-family: 'Oswald', sans-serif; font-weight: 600; font-size: 14px; min-height: 48px; letter-spacing: 1px; text-transform: uppercase; background: var(--navy); color: #fff; border: none; transition: all 0.18s ease; box-shadow: 0 6px 16px rgba(0,0,0,0.25); } .record-toggle:hover { background: var(--navy-darker); transform: translateY(-1px); } .record-toggle .dot { width: 11px; height: 11px; border-radius: 50%; background: #ff5252; transition: all 0.18s ease; flex-shrink: 0; } .record-toggle.recording { background: #d11; box-shadow: 0 6px 16px rgba(209,17,17,0.3); } .record-toggle.recording:hover { background: #b80f0f; } .record-toggle.recording .dot { background: #fff; border-radius: 3px; animation: blink 1.2s ease-in-out infinite; } @keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } } /* ---- Transcript ---- */ .transcript { width: 100%; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; min-height: clamp(120px, 30vh, 150px); max-height: clamp(200px, 40vh, 280px); overflow-y: auto; padding: 18px 20px; font-size: 16px; line-height: 1.7; font-weight: 400; color: var(--ink); -webkit-overflow-scrolling: touch; } .transcript:empty::before { content: "Your words will appear here as you speak…"; color: var(--gray-9); font-style: italic; } .interim { color: var(--gray-9); } .field { width: 100%; } .field label { display: block; font-family: 'Oswald', sans-serif; font-size: 11px; font-weight: 500; letter-spacing: 1.5px; text-transform: uppercase; color: var(--gray-9); margin-bottom: 7px; } .field input { width: 100%; padding: 14px 15px; border-radius: 11px; background: var(--paper); border: 1.5px solid var(--line); color: var(--ink); font-family: inherit; font-size: 16px; font-weight: 500; } .field input:focus { outline: none; border-color: var(--navy); box-shadow: 0 0 0 3px rgba(0,0,0,0.1); } .actions { display: flex; gap: clamp(8px, 2.5vw, 12px); width: 100%; } .btn { flex: 1; padding: 14px 8px; border-radius: 12px; cursor: pointer; font-family: 'Oswald', sans-serif; min-height: 48px; font-weight: 600; font-size: clamp(12px, 3vw, 13px); letter-spacing: 0.8px; text-transform: uppercase; transition: all 0.18s ease; border: 1.5px solid var(--line); background: var(--paper); color: var(--navy); } .btn:hover:not(:disabled) { border-color: var(--navy); } .btn-primary { background: var(--navy); border-color: var(--navy); color: #fff; } .btn-primary:hover:not(:disabled) { background: var(--navy-darker); box-shadow: 0 6px 18px rgba(0,0,0,0.3); } .btn:disabled { opacity: 0.4; cursor: not-allowed; } footer { padding: 16px clamp(18px, 5vw, 32px); border-top: 1px solid var(--line); color: var(--gray-9); font-size: 10.5px; text-align: center; letter-spacing: 0.5px; font-weight: 500; background: var(--panel); } /* ---- Toast ---- */ .toast { position: fixed; bottom: 28px; left: 50%; transform: translateX(-50%) translateY(80px); background: var(--navy); color: #fff; border-left: 4px solid var(--yellow); padding: 13px 22px; border-radius: 10px; font-size: 13px; font-weight: 600; letter-spacing: 0.3px; opacity: 0; transition: all 0.35s cubic-bezier(.2,.8,.2,1); box-shadow: var(--shadow); z-index: 60; } .toast.show { transform: translateX(-50%) translateY(0); opacity: 1; } .toast.err { border-left-color: #ff5252; } /* ---- Modal ---- */ .modal-backdrop { position: fixed; inset: 0; background: rgba(0,34,75,0.55); backdrop-filter: blur(4px); display: grid; place-items: center; opacity: 0; pointer-events: none; transition: opacity 0.22s ease; z-index: 50; } .modal-backdrop.show { opacity: 1; pointer-events: auto; } .modal { width: 90%; max-width: 430px; background: var(--paper); border-radius: 18px; padding: 28px; box-shadow: var(--shadow); transform: translateY(14px) scale(0.98); transition: transform 0.22s cubic-bezier(.2,.8,.2,1); border-top: 5px solid var(--yellow); } .modal-backdrop.show .modal { transform: translateY(0) scale(1); } .modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; } .modal-head h2 { font-family: 'Oswald', sans-serif; font-weight: 600; font-size: 24px; color: var(--navy); letter-spacing: 0.5px; text-transform: uppercase; } .modal-close { background: transparent; border: none; color: var(--gray-9); font-size: 28px; line-height: 1; cursor: pointer; transition: color 0.15s ease; } .modal-close:hover { color: var(--navy); } .modal .actions { margin-top: 24px; } .hint { color: var(--gray-9); font-size: 11px; margin-top: 7px; line-height: 1.5; font-weight: 500; } /* ---- Small phones: stack action buttons, free up header space ---- */ @media (max-width: 420px) { .header-tag { display: none; } .actions { flex-wrap: wrap; } .actions .btn { flex: 1 1 calc(50% - 5px); } .actions .btn-primary { flex-basis: 100%; } } /* ---- Short landscape (e.g. phone on its side): tighten vertical rhythm ---- */ @media (max-height: 560px) and (orientation: landscape) { body { align-items: flex-start; } .stage { gap: 12px; padding-top: 18px; padding-bottom: 18px; } .mic-wrap { width: 92px; height: 92px; } .mic { width: 72px; height: 72px; } .mic svg { width: 30px; height: 30px; } .timer { font-size: 24px; } .transcript { min-height: 90px; } } /* ---- Large screens: a touch more presence ---- */ @media (min-width: 1000px) { .app { max-width: 720px; } } /* ---- Respect reduced-motion preference ---- */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } } </style> </head> <body> <div class="app" id="app"> <header> <div class="logo"> <img src="data:image/png;base64,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" alt="Winslow"> </div> <div class="header-right"> <button class="gear" id="gearBtn" title="Settings" aria-label="Settings"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="3"/> <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/> </svg> </button> </div> </header> <div class="app-title">HSEQ Transcriber</div> <div class="stage"> <div class="mic-wrap" id="micWrap"> <div class="pulse"></div> <button class="mic" id="micBtn" title="Start / stop recording"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/> <path d="M19 10v2a7 7 0 0 1-14 0v-2"/> <line x1="12" y1="19" x2="12" y2="23"/> <line x1="8" y1="23" x2="16" y2="23"/> </svg> </button> </div> <div class="timer" id="timer">00:00</div> <div class="status" id="status">Tap the mic to begin</div> <button class="record-toggle" id="recordToggle"> <span class="dot"></span> <span id="recordLabel">Start Recording</span> </button> <div class="transcript" id="transcript"></div> <div class="field"> <label for="email">Send transcript to (secure email)</label> <input type="email" id="email" placeholder="name@example.com" autocomplete="email"> </div> <div class="actions"> <button class="btn" id="copyBtn" disabled>Copy</button> <button class="btn" id="clearBtn" disabled>Clear</button> <button class="btn btn-primary" id="sendBtn" disabled>Send →</button> </div> </div> <footer>Audio & transcription stay in your browser until you choose to send.</footer> </div> <div class="modal-backdrop" id="modalBackdrop"> <div class="modal" role="dialog" aria-modal="true" aria-labelledby="modalTitle"> <div class="modal-head"> <h2 id="modalTitle">Settings</h2> <button class="modal-close" id="modalClose" aria-label="Close">×</button> </div> <div class="field"> <label for="settingsEmail">Default recipient email</label> <input type="email" id="settingsEmail" placeholder="name@example.com" autocomplete="email"> <p class="hint">Saved on this device and used to pre-fill the send field.</p> </div> <div class="actions"> <button class="btn" id="settingsCancel">Cancel</button> <button class="btn btn-primary" id="settingsSave">Save</button> </div> </div> </div> <div class="toast" id="toast"></div> <script> (function () { const micBtn = document.getElementById('micBtn'); const micWrap = document.getElementById('micWrap'); const recordToggle = document.getElementById('recordToggle'); const recordLabel = document.getElementById('recordLabel'); const statusEl = document.getElementById('status'); const timerEl = document.getElementById('timer'); const transcriptEl = document.getElementById('transcript'); const emailEl = document.getElementById('email'); const copyBtn = document.getElementById('copyBtn'); const clearBtn = document.getElementById('clearBtn'); const sendBtn = document.getElementById('sendBtn'); const toast = document.getElementById('toast'); const gearBtn = document.getElementById('gearBtn'); const modalBackdrop = document.getElementById('modalBackdrop'); const modalClose = document.getElementById('modalClose'); const settingsEmail = document.getElementById('settingsEmail'); const settingsSave = document.getElementById('settingsSave'); const settingsCancel = document.getElementById('settingsCancel'); const STORE_KEY = 'hseq.transcriber.defaultEmail'; let recognizing = false; let finalText = ''; let recognition = null; let mediaRecorder = null; let stream = null; let seconds = 0, timerInt = null; const SR = window.SpeechRecognition || window.webkitSpeechRecognition; function showToast(msg, isErr) { toast.textContent = msg; toast.className = 'toast show' + (isErr ? ' err' : ''); setTimeout(() => { toast.className = 'toast'; }, 3200); } function fmt(s) { const m = String(Math.floor(s / 60)).padStart(2, '0'); const ss = String(s % 60).padStart(2, '0'); return m + ':' + ss; } function updateButtons() { const has = finalText.trim().length > 0; copyBtn.disabled = !has; clearBtn.disabled = !has; sendBtn.disabled = !has; } function render(interim) { transcriptEl.innerHTML = finalText.replace(/</g, '<') + (interim ? '<span class="interim">' + interim.replace(/</g, '<') + '</span>' : ''); transcriptEl.scrollTop = transcriptEl.scrollHeight; } function setupRecognition() { if (!SR) return null; const r = new SR(); r.continuous = true; r.interimResults = true; r.lang = navigator.language || 'en-AU'; r.onresult = (e) => { let interim = ''; for (let i = e.resultIndex; i < e.results.length; i++) { const t = e.results[i][0].transcript; if (e.results[i].isFinal) finalText += t + ' '; else interim += t; } render(interim); updateButtons(); }; r.onerror = (e) => { if (e.error === 'not-allowed' || e.error === 'service-not-allowed') { showToast('Microphone permission denied', true); stop(); } }; r.onend = () => { if (recognizing) { try { r.start(); } catch (_) {} } }; return r; } async function start() { if (!SR) { showToast('Live transcription needs Chrome or Edge', true); return; } try { stream = await navigator.mediaDevices.getUserMedia({ audio: true }); } catch (err) { showToast('Could not access microphone', true); return; } try { mediaRecorder = new MediaRecorder(stream); mediaRecorder.start(); } catch (_) { mediaRecorder = null; } recognition = setupRecognition(); try { recognition.start(); } catch (_) {} recognizing = true; seconds = 0; timerEl.textContent = '00:00'; timerInt = setInterval(() => { seconds++; timerEl.textContent = fmt(seconds); }, 1000); micWrap.classList.add('recording'); recordToggle.classList.add('recording'); recordLabel.textContent = 'Stop Recording'; statusEl.textContent = 'Recording — listening'; statusEl.classList.add('live'); } function stop() { recognizing = false; if (recognition) { try { recognition.stop(); } catch (_) {} } if (mediaRecorder && mediaRecorder.state !== 'inactive') { try { mediaRecorder.stop(); } catch (_) {} } if (stream) stream.getTracks().forEach(t => t.stop()); clearInterval(timerInt); micWrap.classList.remove('recording'); statusEl.classList.remove('live'); recordToggle.classList.remove('recording'); recordLabel.textContent = 'Start Recording'; statusEl.textContent = finalText.trim() ? 'Stopped — ready to send' : 'Tap the mic to begin'; render(''); updateButtons(); } micBtn.addEventListener('click', () => recognizing ? stop() : start()); recordToggle.addEventListener('click', () => recognizing ? stop() : start()); copyBtn.addEventListener('click', async () => { try { await navigator.clipboard.writeText(finalText.trim()); showToast('Transcript copied'); } catch (_) { showToast('Copy failed', true); } }); clearBtn.addEventListener('click', () => { finalText = ''; render(''); updateButtons(); statusEl.textContent = 'Tap the mic to begin'; timerEl.textContent = '00:00'; }); sendBtn.addEventListener('click', () => { const email = emailEl.value.trim(); const body = finalText.trim(); if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) { showToast('Enter a valid email address', true); emailEl.focus(); return; } if (!body) { showToast('Nothing to send yet', true); return; } const subject = encodeURIComponent('Voice transcript — ' + new Date().toLocaleString()); window.location.href = 'mailto:' + encodeURIComponent(email) + '?subject=' + subject + '&body=' + encodeURIComponent(body); showToast('Opening your email client…'); }); if (!SR) statusEl.textContent = 'Use Chrome/Edge for live transcription'; // ---- Settings (default email) ---- function loadEmail() { try { return localStorage.getItem(STORE_KEY) || ''; } catch (_) { return ''; } } function saveEmail(v) { try { localStorage.setItem(STORE_KEY, v); } catch (_) {} } const savedEmail = loadEmail(); if (savedEmail) emailEl.value = savedEmail; function openModal() { settingsEmail.value = emailEl.value.trim() || loadEmail(); modalBackdrop.classList.add('show'); setTimeout(() => settingsEmail.focus(), 120); } function closeModal() { modalBackdrop.classList.remove('show'); } gearBtn.addEventListener('click', openModal); modalClose.addEventListener('click', closeModal); settingsCancel.addEventListener('click', closeModal); modalBackdrop.addEventListener('click', (e) => { if (e.target === modalBackdrop) closeModal(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeModal(); }); settingsSave.addEventListener('click', () => { const v = settingsEmail.value.trim(); if (v && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v)) { showToast('Enter a valid email address', true); settingsEmail.focus(); return; } saveEmail(v); emailEl.value = v; closeModal(); showToast(v ? 'Default email saved' : 'Default email cleared'); }); })(); </script> </body> </html>
Save
cmd:
run