diff --git a/I38.html b/I38.html
deleted file mode 100644
index 5dda42f..0000000
--- a/I38.html
+++ /dev/null
@@ -1,566 +0,0 @@
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
-<head>
-  <meta charset="utf-8" />
-  <meta name="generator" content="pandoc" />
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
-  <title>Welcome to I38</title>
-  <style>
-    html {
-      color: #1a1a1a;
-      background-color: #fdfdfd;
-    }
-    body {
-      margin: 0 auto;
-      max-width: 36em;
-      padding-left: 50px;
-      padding-right: 50px;
-      padding-top: 50px;
-      padding-bottom: 50px;
-      hyphens: auto;
-      overflow-wrap: break-word;
-      text-rendering: optimizeLegibility;
-      font-kerning: normal;
-    }
-    @media (max-width: 600px) {
-      body {
-        font-size: 0.9em;
-        padding: 12px;
-      }
-      h1 {
-        font-size: 1.8em;
-      }
-    }
-    @media print {
-      html {
-        background-color: white;
-      }
-      body {
-        background-color: transparent;
-        color: black;
-        font-size: 12pt;
-      }
-      p, h2, h3 {
-        orphans: 3;
-        widows: 3;
-      }
-      h2, h3, h4 {
-        page-break-after: avoid;
-      }
-    }
-    p {
-      margin: 1em 0;
-    }
-    a {
-      color: #1a1a1a;
-    }
-    a:visited {
-      color: #1a1a1a;
-    }
-    img {
-      max-width: 100%;
-    }
-    svg {
-      height: auto;
-      max-width: 100%;
-    }
-    h1, h2, h3, h4, h5, h6 {
-      margin-top: 1.4em;
-    }
-    h5, h6 {
-      font-size: 1em;
-      font-style: italic;
-    }
-    h6 {
-      font-weight: normal;
-    }
-    ol, ul {
-      padding-left: 1.7em;
-      margin-top: 1em;
-    }
-    li > ol, li > ul {
-      margin-top: 0;
-    }
-    blockquote {
-      margin: 1em 0 1em 1.7em;
-      padding-left: 1em;
-      border-left: 2px solid #e6e6e6;
-      color: #606060;
-    }
-    code {
-      font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
-      font-size: 85%;
-      margin: 0;
-      hyphens: manual;
-    }
-    pre {
-      margin: 1em 0;
-      overflow: auto;
-    }
-    pre code {
-      padding: 0;
-      overflow: visible;
-      overflow-wrap: normal;
-    }
-    .sourceCode {
-     background-color: transparent;
-     overflow: visible;
-    }
-    hr {
-      border: none;
-      border-top: 1px solid #1a1a1a;
-      height: 1px;
-      margin: 1em 0;
-    }
-    table {
-      margin: 1em 0;
-      border-collapse: collapse;
-      width: 100%;
-      overflow-x: auto;
-      display: block;
-      font-variant-numeric: lining-nums tabular-nums;
-    }
-    table caption {
-      margin-bottom: 0.75em;
-    }
-    tbody {
-      margin-top: 0.5em;
-      border-top: 1px solid #1a1a1a;
-      border-bottom: 1px solid #1a1a1a;
-    }
-    th {
-      border-top: 1px solid #1a1a1a;
-      padding: 0.25em 0.5em 0.25em 0.5em;
-    }
-    td {
-      padding: 0.125em 0.5em 0.25em 0.5em;
-    }
-    header {
-      margin-bottom: 4em;
-      text-align: center;
-    }
-    #TOC li {
-      list-style: none;
-    }
-    #TOC ul {
-      padding-left: 1.3em;
-    }
-    #TOC > ul {
-      padding-left: 0;
-    }
-    #TOC a:not(:hover) {
-      text-decoration: none;
-    }
-    code{white-space: pre-wrap;}
-    span.smallcaps{font-variant: small-caps;}
-    div.columns{display: flex; gap: min(4vw, 1.5em);}
-    div.column{flex: auto; overflow-x: auto;}
-    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
-    /* The extra [class] is a hack that increases specificity enough to
-       override a similar rule in reveal.js */
-    ul.task-list[class]{list-style: none;}
-    ul.task-list li input[type="checkbox"] {
-      font-size: inherit;
-      width: 0.8em;
-      margin: 0 0.8em 0.2em -1.6em;
-      vertical-align: middle;
-    }
-    .display.math{display: block; text-align: center; margin: 0.5rem auto;}
-  </style>
-</head>
-<body>
-<header id="title-block-header">
-<h1 class="title">Welcome to I38</h1>
-</header>
-<h1 id="welcome-to-i38---accessible-i3-window-manager">Welcome to I38 -
-Accessible i3 Window Manager</h1>
-<blockquote>
-<p><strong>Note:</strong> This help guide has been tailored to your
-specific configuration. You’ve chosen <strong>BROWSER</strong> as your
-web browser, <strong>MODKEY</strong> as your mod key, and you’re using
-the <strong>SCREENREADER</strong> screen reader.</p>
-</blockquote>
-<h2 id="introduction-to-i38">Introduction to I38</h2>
-<p>I38 is a configuration for the i3 window manager that makes it more
-accessible for blind people. It features audio feedback, screen reader
-integration, and keyboard shortcuts designed for non-visual
-navigation.</p>
-<p>Unlike traditional desktop environments like GNOME or MATE, i3 is a
-tiling window manager, which means windows are arranged in a
-non-overlapping layout. This can be more efficient to navigate by
-keyboard, as windows are organized in a predictable structure.</p>
-<h3 id="coming-from-gnome-or-mate">Coming from GNOME or MATE?</h3>
-<p>If you’re transitioning from GNOME or MATE, here are some key
-differences to understand:</p>
-<ul>
-<li><strong>Window Management</strong>: In GNOME/MATE, windows can
-overlap freely and are typically manipulated with a mouse. In i3/I38,
-windows tile automatically and are primarily controlled with keyboard
-shortcuts.</li>
-<li><strong>Panels and Indicators</strong>: Instead of persistent panels
-with menus and indicators, I38 uses keyboard shortcuts to access
-functionality.</li>
-<li><strong>Workspace Navigation</strong>: While GNOME/MATE have
-workspaces that you can switch between, I38’s workspaces are more
-central to the workflow and are accessed via dedicated keyboard
-shortcuts.</li>
-<li><strong>Application Launching</strong>: Rather than using a start
-menu or activities overview, I38 provides keyboard shortcuts for
-launching applications.</li>
-</ul>
-<p>I38 has been configured to make this transition easier by providing a
-tabbed layout (similar to browser tabs) and shortcuts that may feel
-somewhat familiar.</p>
-<h2 id="basic-concepts">Basic Concepts</h2>
-<h3 id="workspaces">Workspaces</h3>
-<p>Workspaces act like virtual desktops, allowing you to organize
-applications. You have 10 workspaces available.</p>
-<ul>
-<li>Switch to workspace: <code>Control</code> + <code>F1</code> through
-<code>F10</code></li>
-<li>Move window to workspace: <code>Control</code> + <code>Shift</code>
-+ <code>F1</code> through <code>F10</code></li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> Similar to workspaces in GNOME/MATE,
-but with dedicated keyboard shortcuts rather than overview modes or
-workspace switchers.</p>
-<h3 id="window-management">Window Management</h3>
-<p>Windows in I38 are arranged in a tabbed layout by default, which
-means windows take up the entire screen and you can switch between them
-like browser tabs.</p>
-<ul>
-<li>Switch between windows: <code>Alt</code> + <code>Tab</code> (next)
-or <code>Alt</code> + <code>Shift</code> + <code>Tab</code>
-(previous)</li>
-<li>Launch terminal: <code>MODKEY</code> + <code>Return</code></li>
-<li>Close window: <code>MODKEY</code> + <code>F4</code></li>
-<li>Toggle fullscreen: <code>MODKEY</code> + <code>BackSpace</code></li>
-<li>List windows in current workspace: <code>RATPOISONKEY</code> then
-<code>'</code> (apostrophe)</li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> Alt+Tab works similarly to
-GNOME/MATE, but window placement is automatic rather than manual.</p>
-<h2 id="modes-in-i38">Modes in I38</h2>
-<h3 id="default-mode">Default Mode</h3>
-<p>This is the standard mode for working with applications. Most
-commands start with your mod key (<code>MODKEY</code>).</p>
-<h3 id="ratpoison-mode">Ratpoison Mode</h3>
-<p>Ratpoison mode allows quick access to common actions using shorter
-key combinations. To enter Ratpoison mode, press
-<code>RATPOISONKEY</code>. After pressing this key, you can execute
-commands with single keystrokes.</p>
-<p>Common Ratpoison mode commands:</p>
-<table>
-<colgroup>
-<col style="width: 38%" />
-<col style="width: 61%" />
-</colgroup>
-<thead>
-<tr>
-<th>Key</th>
-<th>Action</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td><code>c</code></td>
-<td>Launch a terminal</td>
-</tr>
-<tr>
-<td><code>e</code></td>
-<td>Open text editor (TEXTEDITOR)</td>
-</tr>
-<tr>
-<td><code>w</code></td>
-<td>Launch web browser (BROWSER)</td>
-</tr>
-<tr>
-<td><code>k</code></td>
-<td>Kill (close) the current window</td>
-</tr>
-<tr>
-<td><code>?</code></td>
-<td>Show I38 help</td>
-</tr>
-<tr>
-<td><code>Escape</code> or <code>Control</code> + <code>g</code></td>
-<td>Exit Ratpoison mode without taking action</td>
-</tr>
-<tr>
-<td><code>Shift</code> + <code>c</code></td>
-<td>Restart Cthulhu screen reader</td>
-</tr>
-<tr>
-<td><code>Shift</code> + <code>o</code></td>
-<td>Restart Orca screen reader</td>
-</tr>
-<tr>
-<td><code>Shift</code> + <code>t</code></td>
-<td>Toggle screen reader</td>
-</tr>
-<tr>
-<td><code>Control</code> + <code>;</code></td>
-<td>Reload I38 configuration</td>
-</tr>
-<tr>
-<td><code>Control</code> + <code>q</code></td>
-<td>Exit i3 (log out)</td>
-</tr>
-<tr>
-<td><code>!</code></td>
-<td>Open run dialog</td>
-</tr>
-<tr>
-<td><code>Alt</code> + <code>b</code></td>
-<td>Check battery status</td>
-</tr>
-<tr>
-<td><code>g</code></td>
-<td>Check game controller status</td>
-</tr>
-</tbody>
-</table>
-<p><em>GNOME/MATE comparison:</em> This mode has no direct equivalent in
-GNOME/MATE. Think of it as a command palette or quick launcher activated
-by a single key.</p>
-<h3 id="bypass-mode">Bypass Mode</h3>
-<p>Bypass mode passes all keys directly to the application, which is
-useful for applications that need many keyboard shortcuts. To enter
-bypass mode, press <code>MODKEY</code> + <code>Shift</code> +
-<code>BackSpace</code>. Use the same key combination to exit bypass
-mode.</p>
-<p><em>GNOME/MATE comparison:</em> In GNOME/MATE, applications always
-receive keyboard input directly. Bypass mode simulates this behavior
-within i3.</p>
-<h2 id="accessibility-features">Accessibility Features</h2>
-<h3 id="screen-reader">Screen Reader</h3>
-<p>I38 is configured to work with your screen reader (SCREENREADER). The
-screen reader will provide spoken feedback about what’s happening on
-screen so long as there is a window. If you don’t have a window open and
-need to change something SCREENREADER related, press Control+Alt+d to
-bring up the desktop, then screen reader keys should work.</p>
-<ul>
-<li>Toggle screen reader: <code>RATPOISONKEY</code> then
-<code>Shift</code> + <code>t</code></li>
-<li>Restart screen reader: <code>RATPOISONKEY</code> then
-<code>Shift</code> + <code>o</code> (for Orca) or <code>Shift</code> +
-<code>c</code> (for Cthulhu)</li>
-<li>Interrupt speech: <code>MODKEY</code> + <code>Shift</code> +
-<code>F5</code></li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> GNOME uses Orca by default with its
-own keyboard shortcuts. I38 integrates screen readers more deeply with
-the window manager.</p>
-<h3 id="braille-display-support">Braille Display Support</h3>
-<p>If you’ve enabled braille display support during setup, I38 will
-start XBrlAPI automatically to provide braille output from your screen
-reader.</p>
-<h3 id="ocr-optical-character-recognition">OCR (Optical Character
-Recognition)</h3>
-<p>If installed, you can use OCR to read text from images or
-inaccessible applications:</p>
-<ul>
-<li><code>MODKEY</code> + <code>F5</code>: Perform OCR on the entire
-screen and speak the content</li>
-<li>In Ratpoison mode: <code>Print</code> or <code>MODKEY</code> +
-<code>r</code>: Perform OCR and save to clipboard</li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> OCR features are typically not
-integrated into GNOME/MATE by default.</p>
-<h3 id="sound-effects">Sound Effects</h3>
-<p>I38 provides audio feedback for many actions:</p>
-<ul>
-<li>Window open/close: Ascending/descending tones</li>
-<li>Mode changes: Distinctive sounds for each mode</li>
-<li>Workspace changes: Subtle audio cues</li>
-<li>Fullscreen toggle: Special sound effect</li>
-</ul>
-<p>This audio feedback provides non-visual confirmation of actions and
-state changes.</p>
-<p><em>GNOME/MATE comparison:</em> GNOME/MATE typically have fewer sound
-effects for window management actions.</p>
-<h2 id="application-menu-and-running-programs">Application Menu and
-Running Programs</h2>
-<p>Access applications in multiple ways:</p>
-<ul>
-<li>Applications menu: <code>MODKEY</code> + <code>F1</code></li>
-<li>Run dialog (enter a command): <code>MODKEY</code> + <code>F2</code>
-or in Ratpoison mode, <code>!</code> (exclamation mark)</li>
-<li>Common applications have dedicated shortcuts in Ratpoison mode (see
-table above)</li>
-</ul>
-<p>The applications menu is organized by categories similar to
-traditional desktop environments.</p>
-<p><em>GNOME/MATE comparison:</em> Instead of clicking on application
-icons or using a start menu, I38 provides keyboard shortcuts to access
-applications.</p>
-<h2 id="reminders-and-notifications">Reminders and Notifications</h2>
-<p>I38 includes integration with the <code>remind</code> program for
-managing reminders:</p>
-<ul>
-<li>Access the reminder tool: <code>RATPOISONKEY</code> then
-<code>r</code></li>
-<li>Create various types of reminders (one-time, daily, weekly,
-monthly)</li>
-<li>Get notification alerts for your reminders</li>
-</ul>
-<p>The reminder tool provides the following features:</p>
-<ul>
-<li><strong>One-time Reminders</strong>: Set for a specific date and
-time</li>
-<li><strong>Daily Reminders</strong>: Occur every day at the specified
-time</li>
-<li><strong>Weekly Reminders</strong>: Occur on specific days of the
-week</li>
-<li><strong>Monthly Reminders</strong>: Occur on a specific day each
-month or the last day of each month</li>
-<li><strong>Custom Reminders</strong>: Create complex reminder
-patterns</li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> Similar to calendar applications in
-GNOME/MATE but with a simplified interface optimized for keyboard
-navigation.</p>
-<h2 id="volume-and-media-controls">Volume and Media Controls</h2>
-<h3 id="system-volume">System Volume</h3>
-<ul>
-<li>Increase volume: <code>MODKEY</code> +
-<code>XF86AudioRaiseVolume</code></li>
-<li>Decrease volume: <code>MODKEY</code> +
-<code>XF86AudioLowerVolume</code></li>
-<li>Mute/unmute: <code>MODKEY</code> + <code>XF86AudioMute</code></li>
-</ul>
-<h3 id="media-player-controls">Media Player Controls</h3>
-<ul>
-<li>Play/Pause: <code>XF86AudioPlay</code></li>
-<li>Next track: <code>XF86AudioNext</code></li>
-<li>Previous track: <code>XF86AudioPrev</code></li>
-<li>Stop: <code>XF86AudioStop</code></li>
-<li>Media info: <code>MODKEY</code> + <code>XF86AudioPlay</code></li>
-</ul>
-<p>In Ratpoison mode, these are also available with Alt+Shift
-combinations:</p>
-<ul>
-<li>Increase volume: <code>Alt</code> + <code>Shift</code> +
-<code>=</code></li>
-<li>Decrease volume: <code>Alt</code> + <code>Shift</code> +
-<code>-</code></li>
-<li>Previous track: <code>Alt</code> + <code>Shift</code> +
-<code>z</code></li>
-<li>Pause: <code>Alt</code> + <code>Shift</code> + <code>c</code></li>
-<li>Play: <code>Alt</code> + <code>Shift</code> + <code>x</code></li>
-<li>Stop: <code>Alt</code> + <code>Shift</code> + <code>v</code></li>
-<li>Next track: <code>Alt</code> + <code>Shift</code> +
-<code>b</code></li>
-<li>Media info: <code>Alt</code> + <code>Shift</code> +
-<code>u</code></li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> Media controls are similar to those
-in GNOME/MATE, with the addition of audio feedback.</p>
-<h2 id="file-management">File Management</h2>
-<p>I38 uses FILEBROWSER for file management. Launch it in Ratpoison mode
-with the <code>f</code> key.</p>
-<p><em>GNOME/MATE comparison:</em> Similar functionality to Nautilus
-(GNOME) or Caja (MATE), but launched via keyboard shortcut rather than
-from a desktop icon or menu.</p>
-<h2 id="system-operations">System Operations</h2>
-<ul>
-<li>Reload I38 configuration: In Ratpoison mode, <code>Control</code> +
-<code>;</code> (semicolon)</li>
-<li>Exit i3 (log out): In Ratpoison mode, <code>Control</code> +
-<code>q</code></li>
-<li>Check battery status: In Ratpoison mode, <code>Alt</code> +
-<code>b</code></li>
-<li>Check game controller status: In Ratpoison mode, <code>g</code></li>
-<li>Adjust screen brightness (if xrandr is available): In Ratpoison
-mode, <code>Alt</code> + <code>s</code></li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> These functions are typically
-available through system menus or indicators in GNOME/MATE.</p>
-<h2 id="keyboard-layouts">Keyboard Layouts</h2>
-<p>Switch between layouts: <code>Super</code> + <code>Space</code></p>
-<p>This is only available if you chose multiple keyboard layouts during
-setup.</p>
-<p><em>GNOME/MATE comparison:</em> Similar to keyboard layout switching
-in GNOME/MATE, but with a different default shortcut.</p>
-<h2 id="desktop-and-window-decorations">Desktop and Window
-Decorations</h2>
-<p>Unlike GNOME or MATE, i3 uses minimal window decorations. Windows
-don’t have title bars with minimize/maximize buttons. Instead, windows
-fill their available space automatically, and interactions are performed
-through keyboard shortcuts.</p>
-<ul>
-<li>Show desktop icons: <code>MODKEY</code> + <code>Control</code> +
-<code>d</code></li>
-</ul>
-<h2 id="clipboard-management">Clipboard Management</h2>
-<p>I38 includes clipboard management features:</p>
-<ul>
-<li>Access clipboard history: <code>MODKEY</code> + <code>Control</code>
-+ <code>c</code></li>
-</ul>
-<h2 id="bookmark-management">Bookmark Management</h2>
-<ul>
-<li>Access bookmarks: <code>MODKEY</code> + <code>Control</code> +
-<code>b</code></li>
-</ul>
-<p><em>GNOME/MATE comparison:</em> Bookmarks are typically managed
-within applications in GNOME/MATE. I38 provides a system-wide bookmark
-manager.</p>
-<h2 id="tips-for-new-users">Tips for New Users</h2>
-<ul>
-<li><strong>Start with Ratpoison mode</strong>: Learn the single-key
-commands first, as they’re easier to remember.</li>
-<li><strong>Use the window list</strong>: When you’re lost, use
-<code>RATPOISONKEY</code> then <code>'</code> to show all windows in the
-current workspace.</li>
-<li><strong>Bookmark important websites</strong>: Use
-<code>MODKEY</code> + <code>Control</code> + <code>b</code> to access
-bookmarks.</li>
-<li><strong>Remember the help shortcut</strong>: <code>MODKEY</code> +
-<code>Shift</code> + <code>F1</code> is your friend when you need
-guidance.</li>
-<li><strong>Let the sound effects guide you</strong>: Pay attention to
-the audio cues to understand what’s happening.</li>
-<li><strong>Take advantage of OCR</strong>: If an application isn’t
-accessible, try the OCR function.</li>
-</ul>
-<h3 id="transitioning-from-gnomemate">Transitioning from GNOME/MATE</h3>
-<ul>
-<li>Start by learning the basic navigation shortcuts before exploring
-advanced features</li>
-<li>The tabbed layout should feel somewhat familiar if you’re used to
-browser tabs</li>
-<li>Alt+Tab works similarly to GNOME/MATE for switching between
-windows</li>
-<li>Focus on keyboard commands rather than looking for visual elements
-like panels or docks</li>
-</ul>
-<h2 id="customization">Customization</h2>
-<p>You can customize I38 by editing the file
-<code>~/.config/i3/customizations</code>. This file will not be
-overwritten when you update I38.</p>
-<p>Example customizations:</p>
-<pre><code># Change background color
-exec_always --no-startup-id xsetroot -solid &quot;#2E3440&quot;
-
-# Add custom keybinding
-bindsym $mod+F12 exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ 100%</code></pre>
-<p>To reconfigure I38 completely, run the <code>i38.sh</code> script
-again.</p>
-<p><em>GNOME/MATE comparison:</em> Much more text-based configuration
-compared to the graphical settings dialogs in GNOME/MATE.</p>
-<h2 id="getting-help">Getting Help</h2>
-<p>If you need assistance with I38, you can:</p>
-<ul>
-<li>Press <code>MODKEY</code> + <code>Shift</code> + <code>F1</code> to
-view the help documentation</li>
-<li>Visit the Stormux website at <a
-href="https://stormux.org">stormux.org</a></li>
-<li>Check the i3 documentation at <a
-href="https://i3wm.org/docs/userguide.html">i3wm.org/docs/userguide.html</a></li>
-</ul>
-<hr />
-<p><em>I38 - Making i3 accessible. A Stormux project. License: GPL
-v3</em></p>
-</body>
-</html>
diff --git a/I38.md b/I38.md
new file mode 100644
index 0000000..7106f7f
--- /dev/null
+++ b/I38.md
@@ -0,0 +1,265 @@
+# Welcome to I38 - Accessible i3 Window Manager
+
+> **Note:** This help guide has been tailored to your specific configuration. You've chosen **BROWSER** as your web browser, **MODKEY** as your mod key, and you're using the **SCREENREADER** screen reader.
+
+## Introduction to I38
+
+I38 is a configuration for the i3 window manager that makes it more accessible for blind people. It features audio feedback, screen reader integration, and keyboard shortcuts designed for non-visual navigation.
+
+Unlike traditional desktop environments like GNOME or MATE, i3 is a tiling window manager, which means windows are arranged in a non-overlapping layout. This can be more efficient to navigate by keyboard, as windows are organized in a predictable structure.
+
+### Coming from GNOME or MATE?
+
+If you're transitioning from GNOME or MATE, here are some key differences to understand:
+
+- **Window Management**: In GNOME/MATE, windows can overlap freely and are typically manipulated with a mouse. In i3/I38, windows tile automatically and are primarily controlled with keyboard shortcuts.
+- **Panels and Indicators**: Instead of persistent panels with menus and indicators, I38 uses keyboard shortcuts to access functionality.
+- **Workspace Navigation**: While GNOME/MATE have workspaces that you can switch between, I38's workspaces are more central to the workflow and are accessed via dedicated keyboard shortcuts.
+- **Application Launching**: Rather than using a start menu or activities overview, I38 provides keyboard shortcuts for launching applications.
+
+I38 has been configured to make this transition easier by providing a tabbed layout (similar to browser tabs) and shortcuts that may feel somewhat familiar.
+
+## Basic Concepts
+
+### Workspaces
+
+Workspaces act like virtual desktops, allowing you to organize applications. You have 10 workspaces available.
+
+- Switch to workspace: `Control` + `F1` through `F10`
+- Move window to workspace: `Control` + `Shift` + `F1` through `F10`
+
+*GNOME/MATE comparison:* Similar to workspaces in GNOME/MATE, but with dedicated keyboard shortcuts rather than overview modes or workspace switchers.
+
+### Window Management
+
+Windows in I38 are arranged in a tabbed layout by default, which means windows take up the entire screen and you can switch between them like browser tabs.
+
+- Switch between windows: `Alt` + `Tab` (next) or `Alt` + `Shift` + `Tab` (previous)
+- Launch terminal: `MODKEY` + `Return`
+- Close window: `MODKEY` + `F4`
+- Toggle fullscreen: `MODKEY` + `BackSpace`
+- List windows in current workspace: `RATPOISONKEY` then `'` (apostrophe)
+
+*GNOME/MATE comparison:* Alt+Tab works similarly to GNOME/MATE, but window placement is automatic rather than manual.
+
+## Modes in I38
+
+### Default Mode
+
+This is the standard mode for working with applications. Most commands start with your mod key (`MODKEY`).
+
+### Ratpoison Mode
+
+Ratpoison mode allows quick access to common actions using shorter key combinations. To enter Ratpoison mode, press `RATPOISONKEY`. After pressing this key, you can execute commands with single keystrokes.
+
+Common Ratpoison mode commands:
+
+| Key | Action |
+|-----|--------|
+| `c` | Launch a terminal |
+| `e` | Open text editor (TEXTEDITOR) |
+| `w` | Launch web browser (BROWSER) |
+| `k` | Kill (close) the current window |
+| `?` | Show I38 help |
+| `Escape` or `Control` + `g` | Exit Ratpoison mode without taking action |
+| `Shift` + `c` | Restart Cthulhu screen reader |
+| `Shift` + `o` | Restart Orca screen reader |
+| `Shift` + `t` | Toggle screen reader |
+| `Control` + `;` | Reload I38 configuration |
+| `Control` + `q` | Exit i3 (log out) |
+| `!` | Open run dialog |
+| `Alt` + `b` | Check battery status |
+| `g` | Check game controller status |
+
+*GNOME/MATE comparison:* This mode has no direct equivalent in GNOME/MATE. Think of it as a command palette or quick launcher activated by a single key.
+
+### Bypass Mode
+
+Bypass mode passes all keys directly to the application, which is useful for applications that need many keyboard shortcuts. To enter bypass mode, press `MODKEY` + `Shift` + `BackSpace`. Use the same key combination to exit bypass mode.
+
+*GNOME/MATE comparison:* In GNOME/MATE, applications always receive keyboard input directly. Bypass mode simulates this behavior within i3.
+
+## Accessibility Features
+
+### Screen Reader
+
+I38 is configured to work with your screen reader (SCREENREADER). The screen reader will provide spoken feedback about what's happening on screen so long as there is a window. If you don't have a window open and need to change something SCREENREADER related, press Control+Alt+d to bring up the desktop, then screen reader keys should work.
+
+- Toggle screen reader: `RATPOISONKEY` then `Shift` + `t`
+- Restart screen reader: `RATPOISONKEY` then `Shift` + `o` (for Orca) or `Shift` + `c` (for Cthulhu)
+- Interrupt speech: `MODKEY` + `Shift` + `F5`
+
+*GNOME/MATE comparison:* GNOME uses Orca by default with its own keyboard shortcuts. I38 integrates screen readers more deeply with the window manager.
+
+### Braille Display Support
+
+If you've enabled braille display support during setup, I38 will start XBrlAPI automatically to provide braille output from your screen reader.
+
+### OCR (Optical Character Recognition)
+
+If installed, you can use OCR to read text from images or inaccessible applications:
+
+- `MODKEY` + `F5`: Perform OCR on the entire screen and speak the content
+- In Ratpoison mode: `Print` or `MODKEY` + `r`: Perform OCR and save to clipboard
+
+*GNOME/MATE comparison:* OCR features are typically not integrated into GNOME/MATE by default.
+
+### Sound Effects
+
+I38 provides audio feedback for many actions:
+
+- Window open/close: Ascending/descending tones
+- Mode changes: Distinctive sounds for each mode
+- Workspace changes: Subtle audio cues
+- Fullscreen toggle: Special sound effect
+
+This audio feedback provides non-visual confirmation of actions and state changes.
+
+*GNOME/MATE comparison:* GNOME/MATE typically have fewer sound effects for window management actions.
+
+## Application Menu and Running Programs
+
+Access applications in multiple ways:
+
+- Applications menu: `MODKEY` + `F1`
+- Run dialog (enter a command): `MODKEY` + `F2` or in Ratpoison mode, `!` (exclamation mark)
+- Common applications have dedicated shortcuts in Ratpoison mode (see table above)
+
+The applications menu is organized by categories similar to traditional desktop environments.
+
+*GNOME/MATE comparison:* Instead of clicking on application icons or using a start menu, I38 provides keyboard shortcuts to access applications.
+
+## Reminders and Notifications
+
+I38 includes integration with the `remind` program for managing reminders:
+
+- Access the reminder tool: `RATPOISONKEY` then `r`
+- Create various types of reminders (one-time, daily, weekly, monthly)
+- Get notification alerts for your reminders
+
+The reminder tool provides the following features:
+
+- **One-time Reminders**: Set for a specific date and time
+- **Daily Reminders**: Occur every day at the specified time
+- **Weekly Reminders**: Occur on specific days of the week
+- **Monthly Reminders**: Occur on a specific day each month or the last day of each month
+- **Custom Reminders**: Create complex reminder patterns
+
+*GNOME/MATE comparison:* Similar to calendar applications in GNOME/MATE but with a simplified interface optimized for keyboard navigation.
+
+## Volume and Media Controls
+
+### System Volume
+
+- Increase volume: `MODKEY` + `XF86AudioRaiseVolume`
+- Decrease volume: `MODKEY` + `XF86AudioLowerVolume`
+- Mute/unmute: `MODKEY` + `XF86AudioMute`
+
+### Media Player Controls
+
+- Play/Pause: `XF86AudioPlay`
+- Next track: `XF86AudioNext`
+- Previous track: `XF86AudioPrev`
+- Stop: `XF86AudioStop`
+- Media info: `MODKEY` + `XF86AudioPlay`
+
+In Ratpoison mode, these are also available with Alt+Shift combinations:
+
+- Increase volume: `Alt` + `Shift` + `=`
+- Decrease volume: `Alt` + `Shift` + `-`
+- Previous track: `Alt` + `Shift` + `z`
+- Pause: `Alt` + `Shift` + `c`
+- Play: `Alt` + `Shift` + `x`
+- Stop: `Alt` + `Shift` + `v`
+- Next track: `Alt` + `Shift` + `b`
+- Media info: `Alt` + `Shift` + `u`
+
+*GNOME/MATE comparison:* Media controls are similar to those in GNOME/MATE, with the addition of audio feedback.
+
+## File Management
+
+I38 uses FILEBROWSER for file management. Launch it in Ratpoison mode with the `f` key.
+
+*GNOME/MATE comparison:* Similar functionality to Nautilus (GNOME) or Caja (MATE), but launched via keyboard shortcut rather than from a desktop icon or menu.
+
+## System Operations
+
+- Reload I38 configuration: In Ratpoison mode, `Control` + `;` (semicolon)
+- Exit i3 (log out): In Ratpoison mode, `Control` + `q`
+- Check battery status: In Ratpoison mode, `Alt` + `b`
+- Check game controller status: In Ratpoison mode, `g`
+- Adjust screen brightness (if xrandr is available): In Ratpoison mode, `Alt` + `s`
+
+*GNOME/MATE comparison:* These functions are typically available through system menus or indicators in GNOME/MATE.
+
+## Keyboard Layouts
+
+Switch between layouts: `Super` + `Space`
+
+This is only available if you chose multiple keyboard layouts during setup.
+
+*GNOME/MATE comparison:* Similar to keyboard layout switching in GNOME/MATE, but with a different default shortcut.
+
+## Desktop and Window Decorations
+
+Unlike GNOME or MATE, i3 uses minimal window decorations. Windows don't have title bars with minimize/maximize buttons. Instead, windows fill their available space automatically, and interactions are performed through keyboard shortcuts.
+
+- Show desktop icons: `MODKEY` + `Control` + `d`
+
+## Clipboard Management
+
+I38 includes clipboard management features:
+
+- Access clipboard history: `MODKEY` + `Control` + `c`
+
+## Bookmark Management
+
+- Access bookmarks: `MODKEY` + `Control` + `b`
+
+*GNOME/MATE comparison:* Bookmarks are typically managed within applications in GNOME/MATE. I38 provides a system-wide bookmark manager.
+
+## Tips for New Users
+
+- **Start with Ratpoison mode**: Learn the single-key commands first, as they're easier to remember.
+- **Use the window list**: When you're lost, use `RATPOISONKEY` then `'` to show all windows in the current workspace.
+- **Bookmark important websites**: Use `MODKEY` + `Control` + `b` to access bookmarks.
+- **Remember the help shortcut**: `MODKEY` + `Shift` + `F1` is your friend when you need guidance.
+- **Let the sound effects guide you**: Pay attention to the audio cues to understand what's happening.
+- **Take advantage of OCR**: If an application isn't accessible, try the OCR function.
+
+### Transitioning from GNOME/MATE
+
+- Start by learning the basic navigation shortcuts before exploring advanced features
+- The tabbed layout should feel somewhat familiar if you're used to browser tabs
+- Alt+Tab works similarly to GNOME/MATE for switching between windows
+- Focus on keyboard commands rather than looking for visual elements like panels or docks
+
+## Customization
+
+You can customize I38 by editing the file `~/.config/i3/customizations`. This file will not be overwritten when you update I38.
+
+Example customizations:
+
+```
+# Change background color
+exec_always --no-startup-id xsetroot -solid "#2E3440"
+
+# Add custom keybinding
+bindsym $mod+F12 exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ 100%
+```
+
+To reconfigure I38 completely, run the `i38.sh` script again.
+
+*GNOME/MATE comparison:* Much more text-based configuration compared to the graphical settings dialogs in GNOME/MATE.
+
+## Getting Help
+
+If you need assistance with I38, you can:
+
+- Press `MODKEY` + `Shift` + `F1` to view the help documentation
+- Visit the Stormux website at [stormux.org](https://stormux.org)
+- Check the i3 documentation at [i3wm.org/docs/userguide.html](https://i3wm.org/docs/userguide.html)
+
+---
+
+*I38 - Making i3 accessible. A Stormux project. License: GPL v3*
diff --git a/README.md b/README.md
index ba29769..93472aa 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,7 @@ An uppercase I looks like a 1, 3 from i3, and 8 because the song [We Are 138](ht
 - notification-daemon: To handle notifications
 - xfce4-notifyd: For sending notifications Replaces  notification-daemon (Sway user will need to install the customized variant at <https://github.com/icasdri/xfce4-notifyd-layer-shell>)
 - ocrdesktop: For getting contents of the current window with OCR.
+- pandoc or markdown: To generate html files.
 - pamixer: for the mute-unmute script
 - pcmanfm: [optional] Graphical file manager.
 - playerctl: music controls
diff --git a/i38.sh b/i38.sh
index eb57208..d50b108 100755
--- a/i38.sh
+++ b/i38.sh
@@ -33,6 +33,11 @@ if [[ -n "${missing}" ]]; then
     echo "${missing[*]}"
     exit 1
 fi
+if ! command -v pandoc &> /dev/null && ! command -v markdown &> /dev/null ; then
+    echo "Please install either pandoc or markdown."
+    echo "The markdown command may be provided by the package discount."
+    exit 1
+fi
 
 keyboard_menu() {
     keyboardMenu=("us" "English (US)"
@@ -539,9 +544,6 @@ bindsym Control+F8 workspace number \$ws8, exec --no-startup-id ${i3Path}/script
 bindsym Control+F9 workspace number \$ws9, exec --no-startup-id ${i3Path}/scripts/announce_workspace.sh
 bindsym Control+F10 workspace number \$ws10, exec --no-startup-id ${i3Path}/scripts/announce_workspace.sh
 
-# This is sort of a fake panel where some useful but seldom interacted with applications can live.
-bindsym Control+Mod1+Tab workspace number 11, exec --no-startup-id ${i3Path}/scripts/announce_workspace.sh
-
 # move focused container to workspace
 bindsym Control+Shift+F1 move container to workspace number \$ws1, exec spd-say -P important -Cw "moved to workspace 1"
 bindsym Control+Shift+F2 move container to workspace number \$ws2, exec spd-say -P important -Cw "moved to workspace 2"
@@ -578,6 +580,23 @@ if [[ ${#kbd[@]} -gt 1 ]]; then
     echo "bindsym Mod4+space exec ${i3Path}/scripts/keyboard.sh cycle ${kbd[@]}" >> ${i3Path}/config
 fi
 
+# Create panel mode
+cat << EOF >> ${i3Path}/config
+# Panel mode configuration
+bindsym Control+Mod1+Tab mode "panel"
+mode "panel" {
+    # Weather information bound to w
+    bindsym w exec --no-startup-id ${i3Path}/scripts/weather.sh, mode "default"
+    
+    # System information bound to s
+    bindsym s exec --no-startup-id ${i3Path}/scripts/sysinfo.sh, mode "default"
+    
+    # Exit panel mode without any action
+    bindsym Escape mode "default"
+    bindsym Control+g mode "default"
+}
+EOF
+
 # Create ratpoison mode if requested.
 if [[ -n "${escapeKey}" ]]; then
     cat << EOF >> ${i3Path}/config
@@ -641,7 +660,7 @@ bindsym Mod1+Shift+u exec --no-startup-id play -qV0 "| sox -np synth 0.03 sin 20
 #Check battery status
 bindsym Mod1+b exec --no-startup-id ${i3Path}/scripts/battery_status.sh, mode "default"
 #Check controller battery status
-bindsym g exec ${i3Path}/scripts/game_controler.sh -s, mode "default"
+bindsym g exec ${i3Path}/scripts/game_controller.sh -s, mode "default"
 # Get a list of windows in the current workspace
 bindsym apostrophe exec --no-startup-id ${i3Path}/scripts/window_list.sh, mode "default"
 # Restart Cthulhu
@@ -676,7 +695,7 @@ fi
 
 cat << EOF >> ${i3Path}/config
 # Auto start section
-$(if [[ $sounzzds -eq 0 ]]; then
+$(if [[ $sounds -eq 0 ]]; then
     if [[ $usingSway -eq 0 ]]; then
         echo "exec --no-startup-id ${i3Path}/scripts/sound.py"
     else
@@ -725,19 +744,34 @@ fi)
 # First run help documentation
 exec --no-startup-id bash -c 'if [[ -f "${i3Path}/firstrun" ]]; then ${webBrowser} "${i3Path}/I38.html"& rm "${i3Path}/firstrun"; fi'
 
-# Fake panel setup
-exec --no-startup-id i3-msg 'workspace 11; workspace 1'
-
 # If you want to add personal customizations to i3, add them in ${i3Path}/customizations
 # It is not overwritten when the config file is recreated.
     include "${i3Path}/customizations"
-# Applications that will be placed in workspace 11, which we use as a sort of fake panel.
-    include "${i3Path}/panel.conf"
 EOF
 touch "${i3Path}/customizations"
-cp -v panel.conf "${i3Path}/panel.conf"
-# Move html help file to destination
-cp -v I38.html "${i3Path}/I38.html"
+# Check for markdown or pandoc for converting the welcome document
+if command -v pandoc &> /dev/null ; then
+    pandoc -f markdown -t html "I38.md" -so "${i3Path}/I38.html" --metadata title="Welcome to I38"
+elif command -v markdown &> /dev/null ; then
+    cat << EOF > "${i3Path}/I38.html"
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Welcome to I38</title>
+    <meta charset="utf-8">
+</head>
+<body>
+EOF
+    
+    # Convert markdown to html and append to the file
+    markdown "I38.md" >> "${i3Path}/I38.html"
+    
+    # Close the HTML tags using heredoc
+    cat << EOF >> "${i3Path}/I38.html"
+</body>
+</html>
+EOF
+fi
 
 # More readable version of variables.
 escapeKey="${escapeKey//Mod1/Alt}"
diff --git a/scripts/game_controler.sh b/scripts/game_controller.sh
similarity index 100%
rename from scripts/game_controler.sh
rename to scripts/game_controller.sh
diff --git a/scripts/sysinfo.sh b/scripts/sysinfo.sh
new file mode 100755
index 0000000..3cd8a3d
--- /dev/null
+++ b/scripts/sysinfo.sh
@@ -0,0 +1,110 @@
+#!/usr/bin/env bash
+
+
+# Initialize variables
+cpuUsage=0
+cpuTemp=0
+memoryUsed=0
+memoryTotal=0
+memoryPercent=0
+swapUsed=0
+swapTotal=0
+swapPercent=0
+diskUsed=0
+diskTotal=0
+diskPercent=0
+networkSent=0
+networkRecv=0
+
+# Helper function for temperature conversion
+celsius_to_fahrenheit() {
+    local celsius="$1"
+    [[ -z "$celsius" || "$celsius" == "--" ]] && echo "--" && return
+    [[ ! "$celsius" =~ ^-?[0-9]+(\.[0-9]+)?$ ]] && echo "--" && return
+    
+    local fahrenheit
+    fahrenheit=$(echo "scale=1; ($celsius * 9/5) + 32" | bc -l)
+    echo "$fahrenheit"
+}
+
+update_system_data() {
+    # CPU usage
+    cpuUsage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
+    cpuUsage=$(printf "%.1f" "$cpuUsage" 2>/dev/null || echo "$cpuUsage")
+    
+    # CPU temperature - fix for high readings
+    local tempCelsius="--"
+    if [[ -f /sys/class/thermal/thermal_zone0/temp ]]; then
+        tempCelsius=$(cat /sys/class/thermal/thermal_zone0/temp)
+        # Check if we need to divide by 1000 (common format)
+        if [[ $tempCelsius -gt 200 ]]; then
+            tempCelsius=$(echo "scale=1; $tempCelsius/1000" | bc -l)
+        fi
+    elif [[ -f /sys/class/hwmon/hwmon0/temp1_input ]]; then
+        tempCelsius=$(cat /sys/class/hwmon/hwmon0/temp1_input)
+        if [[ $tempCelsius -gt 200 ]]; then
+            tempCelsius=$(echo "scale=1; $tempCelsius/1000" | bc -l)
+        fi
+    elif command -v sensors &>/dev/null; then
+        tempCelsius=$(sensors | grep -oP 'Core 0.*?\+\K[0-9.]+')
+    fi
+    
+    [[ "$tempCelsius" != "--" && "$tempCelsius" != "null" ]] && cpuTemp=$(celsius_to_fahrenheit "$tempCelsius") || cpuTemp="--"
+    
+    # Memory usage
+    memoryTotal=$(free -m | awk '/^Mem:/{print $2/1024}')
+    memoryUsed=$(free -m | awk '/^Mem:/{print $3/1024}')
+    memoryPercent=$(free | awk '/^Mem:/{printf("%.1f", $3/$2 * 100)}')
+    
+    # Swap usage
+    swapTotal=$(free -m | awk '/^Swap:/{print $2/1024}')
+    swapUsed=$(free -m | awk '/^Swap:/{print $3/1024}')
+    [[ "$swapTotal" -gt 0 ]] && swapPercent=$(free | awk '/^Swap:/{printf("%.1f", $3/$2 * 100)}') || swapPercent=0
+    
+    # Disk usage
+    diskTotal=$(df -h / | awk 'NR==2 {print $2}')
+    diskUsed=$(df -h / | awk 'NR==2 {print $3}')
+    diskPercent=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
+    
+    # Network usage
+    networkSent=$(cat /proc/net/dev | grep -v "lo:" | awk '{s+=$10} END {printf "%.2f", s/1024/1024}')
+    networkRecv=$(cat /proc/net/dev | grep -v "lo:" | awk '{r+=$2} END {printf "%.2f", r/1024/1024}')
+}
+
+display_system_info() {
+    update_system_data
+    
+    # Create the system information text with proper line breaks
+    systemInfoText="System Information
+
+CPU
+Usage: ${cpuUsage}%
+Temperature: ${cpuTemp}° F
+
+Memory
+Usage: ${memoryUsed} / ${memoryTotal} GB (${memoryPercent}%)
+Swap: ${swapUsed} / ${swapTotal} GB (${swapPercent}%)
+
+Disk (Root Partition)
+Usage: ${diskUsed} / ${diskTotal} GB (${diskPercent}%)
+
+Network (Total Since Boot)
+Received: ${networkRecv} MB
+Sent: ${networkSent} MB
+
+End of text. Press Control+Home to return to the beginning."
+
+    # Display in text-info dialog for screen reader accessibility
+    echo "$systemInfoText" | yad --pname=I38System \
+        --title="I38 System Information" \
+        --text-info \
+        --show-cursor \
+        --width=400 \
+        --height=400 \
+        --center \
+        --button="Close:0"
+}
+
+display_system_info
+
+exit 0
diff --git a/scripts/weather.sh b/scripts/weather.sh
new file mode 100755
index 0000000..6ad0821
--- /dev/null
+++ b/scripts/weather.sh
@@ -0,0 +1,439 @@
+#!/usr/bin/env bash
+
+
+# Configuration settings
+defaultCity="Raleigh, NC"
+defaultLat="35.78"
+defaultLon="-78.64"
+tempUnit="F"
+updateInterval=30
+
+configDir="${XDG_CONFIG_HOME:-$HOME/.config}/stormux/I38"
+configFile="$configDir/weather.conf"
+mkdir -p "$configDir"
+
+# Initialize variables
+cityName="Detecting..."
+latitude=0.0
+longitude=0.0
+currentTemp="--"
+currentHumidity="--"
+currentWindSpeed="--"
+currentWindSpeedMph="--"
+currentConditions="Unknown"
+weatherLastUpdate=0
+severeWeatherAlerted=0
+
+declare -a forecastDates=("--" "--" "--")
+declare -a forecastFormattedDates=("--" "--" "--")
+declare -a forecastMinTemps=("--" "--" "--")
+declare -a forecastMaxTemps=("--" "--" "--")
+declare -a forecastConditions=("Unknown" "Unknown" "Unknown")
+
+declare -A weatherCodes
+weatherCodes[0]="Clear sky"
+weatherCodes[1]="Mainly clear"
+weatherCodes[2]="Partly cloudy"
+weatherCodes[3]="Overcast"
+weatherCodes[45]="Fog"
+weatherCodes[48]="Rime fog"
+weatherCodes[51]="Light drizzle"
+weatherCodes[53]="Moderate drizzle"
+weatherCodes[55]="Dense drizzle"
+weatherCodes[56]="Light freezing drizzle"
+weatherCodes[57]="Dense freezing drizzle"
+weatherCodes[61]="Slight rain"
+weatherCodes[63]="Moderate rain"
+weatherCodes[65]="Heavy rain"
+weatherCodes[66]="Light freezing rain"
+weatherCodes[67]="Heavy freezing rain"
+weatherCodes[71]="Slight snow fall"
+weatherCodes[73]="Moderate snow fall"
+weatherCodes[75]="Heavy snow fall"
+weatherCodes[77]="Snow flurries"
+weatherCodes[80]="Slight rain showers"
+weatherCodes[81]="Moderate rain showers"
+weatherCodes[82]="Heavy rain showers"
+weatherCodes[85]="Slight snow showers"
+weatherCodes[86]="Heavy snow showers"
+weatherCodes[95]="Thunderstorm"
+weatherCodes[96]="Thunderstorm with slight hail"
+weatherCodes[99]="Thunderstorm with heavy hail"
+
+declare -a severeWeatherCodes=(65 67 75 82 86 95 96 99)
+
+# Button return codes
+refreshBtn=0
+quitBtn=1
+settingsBtn=2
+
+trap "pkill -P $$" EXIT INT TERM
+
+# Load configuration if available
+if [ -f "$configFile" ]; then
+    source "$configFile"
+    # Convert lastWeatherUpdate string to integer if it exists
+    [[ -n "$lastWeatherUpdate" ]] && weatherLastUpdate=$lastWeatherUpdate || weatherLastUpdate=0
+    
+    if [[ -n "$city" ]]; then
+        cityName="$city"
+        latitude="$latitude"
+        longitude="$longitude"
+    fi
+    
+    # Try to reload saved weather data
+    if [[ "$weatherLastUpdate" -gt 0 && "$currentTemp" == "--" ]]; then
+        [[ -n "$savedCurrentTemp" ]] && currentTemp="$savedCurrentTemp"
+        [[ -n "$savedCurrentHumidity" ]] && currentHumidity="$savedCurrentHumidity"
+        [[ -n "$savedCurrentConditions" ]] && currentConditions="$savedCurrentConditions"
+        [[ -n "$savedCurrentWindSpeed" ]] && currentWindSpeedMph="$savedCurrentWindSpeed"
+        
+        for i in {0..2}; do
+            varDate="savedForecastDate_$i"
+            varMin="savedForecastMin_$i"
+            varMax="savedForecastMax_$i"
+            varCond="savedForecastCond_$i"
+            
+            [[ -n "${!varDate}" ]] && forecastFormattedDates[$i]="${!varDate}"
+            [[ -n "${!varMin}" ]] && forecastMinTemps[$i]="${!varMin}"
+            [[ -n "${!varMax}" ]] && forecastMaxTemps[$i]="${!varMax}"
+            [[ -n "${!varCond}" ]] && forecastConditions[$i]="${!varCond}"
+        done
+    fi
+fi
+
+# Helper functions
+time_diff() {
+    local timestamp="$1"
+    local now=$(date +%s)
+    local diff=$((now - timestamp))
+    
+    if [ $diff -lt 60 ]; then
+        echo "just now"
+    elif [ $diff -lt 3600 ]; then
+        local minutes=$((diff / 60))
+        echo "$minutes minute$([ $minutes -ne 1 ] && echo "s") ago"
+    elif [ $diff -lt 86400 ]; then
+        local hours=$((diff / 3600))
+        echo "$hours hour$([ $hours -ne 1 ] && echo "s") ago"
+    else
+        local days=$((diff / 86400))
+        echo "$days day$([ $days -ne 1 ] && echo "s") ago"
+    fi
+}
+
+celsius_to_fahrenheit() {
+    local celsius="$1"
+    [[ -z "$celsius" || "$celsius" == "--" ]] && echo "--" && return
+    [[ ! "$celsius" =~ ^-?[0-9]+(\.[0-9]+)?$ ]] && echo "--" && return
+    
+    local fahrenheit
+    fahrenheit=$(echo "scale=1; ($celsius * 9/5) + 32" | bc -l)
+    echo "$fahrenheit"
+}
+
+kmh_to_mph() {
+    local kmh="$1"
+    [[ -z "$kmh" || "$kmh" == "--" ]] && echo "--" && return
+    [[ ! "$kmh" =~ ^-?[0-9]+(\.[0-9]+)?$ ]] && echo "--" && return
+    
+    local mph
+    mph=$(echo "scale=1; $kmh * 0.621371" | bc -l)
+    echo "$mph"
+}
+
+format_date() {
+    local isoDate="$1"
+    [[ -z "$isoDate" || "$isoDate" == "--" ]] && echo "--" && return
+    date -d "$isoDate" "+%A, %B %d" 2>/dev/null || echo "$isoDate"
+}
+
+# Save configuration
+save_config() {
+    cat > "$configFile" << EOF
+city="$cityName"
+latitude="$latitude"
+longitude="$longitude"
+tempUnit=$tempUnit
+updateInterval=$updateInterval
+lastWeatherUpdate=$weatherLastUpdate
+savedCurrentTemp="$currentTemp"
+savedCurrentHumidity="$currentHumidity"
+savedCurrentConditions="$currentConditions"
+savedCurrentWindSpeed="$currentWindSpeedMph"
+savedForecastDate_0="${forecastFormattedDates[0]}"
+savedForecastMin_0="${forecastMinTemps[0]}"
+savedForecastMax_0="${forecastMaxTemps[0]}"
+savedForecastCond_0="${forecastConditions[0]}"
+savedForecastDate_1="${forecastFormattedDates[1]}"
+savedForecastMin_1="${forecastMinTemps[1]}"
+savedForecastMax_1="${forecastMaxTemps[1]}"
+savedForecastCond_1="${forecastConditions[1]}"
+savedForecastDate_2="${forecastFormattedDates[2]}"
+savedForecastMin_2="${forecastMinTemps[2]}"
+savedForecastMax_2="${forecastMaxTemps[2]}"
+savedForecastCond_2="${forecastConditions[2]}"
+EOF
+}
+
+# Play severe weather alert sound using Sox
+play_severe_weather_alert() {
+    if command -v play &>/dev/null; then
+        # Generate alert sound pattern using sox
+        play -nqV0 synth 2 sine 853 sine 960 remix - norm -15 &
+    fi
+    
+    # Also display notification if available
+    if command -v notify-send &>/dev/null; then
+        notify-send "Severe Weather Alert" "Severe weather conditions detected for $cityName: $currentConditions" -u critical
+    fi
+}
+
+# Function to check if a value is in array
+in_array() {
+    local value="$1"
+    shift
+    local array=("$@")
+    
+    for item in "${array[@]}"; do
+        if [[ "$item" == "$value" ]]; then
+            return 0  # True, found in array
+        fi
+    done
+    return 1  # False, not found
+}
+
+# Function to detect location
+get_location() {
+    # Only try location detection if we don't already have a city name
+    if [[ "$cityName" == "Detecting..." ]]; then
+        echo "Attempting to detect location via ipinfo.io..."
+        
+        # Try to fetch location data
+        local locationData
+        locationData=$(curl -s --connect-timeout 5 "https://ipinfo.io/json" 2>/dev/null)
+        
+        if [[ $? -eq 0 && -n "$locationData" && $(echo "$locationData" | jq -e '.city') ]]; then
+            echo "Location data received successfully"
+            cityName=$(echo "$locationData" | jq -r '.city // "Unknown"')
+            local region=$(echo "$locationData" | jq -r '.region // ""')
+            # Add region/state to city name if available
+            [[ -n "$region" ]] && cityName="$cityName, $region"
+            
+            # Extract coordinates directly from the "loc" field
+            local loc=$(echo "$locationData" | jq -r '.loc // "0,0"')
+            latitude=$(echo "$loc" | cut -d',' -f1)
+            longitude=$(echo "$loc" | cut -d',' -f2)
+            save_config
+        else
+            cityName="$defaultCity"
+            latitude="$defaultLat"
+            longitude="$defaultLon"
+            save_config
+        fi
+    fi
+}
+
+# Function to fetch weather data
+fetch_weather_data() {
+    local now=$(date +%s)
+    local elapsedMinutes=$(( (now - weatherLastUpdate) / 60 ))
+    
+    # Only fetch if needed
+    if [[ $weatherLastUpdate -eq 0 || $elapsedMinutes -ge $updateInterval ]]; then
+        local url="https://api.open-meteo.com/v1/forecast?latitude=$latitude&longitude=$longitude&current=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m&daily=weather_code,temperature_2m_max,temperature_2m_min&timezone=auto"
+        local response=$(curl -s --connect-timeout 10 "$url" 2>/dev/null)
+        
+        if [[ $? -eq 0 && -n "$response" && $(echo "$response" | jq -e '.current' 2>/dev/null) ]]; then
+            # Update current weather data
+            local tempCelsius=$(echo "$response" | jq -r '.current.temperature_2m // "--"' 2>/dev/null)
+            [[ "$tempCelsius" != "--" && "$tempCelsius" != "null" ]] && currentTemp=$(celsius_to_fahrenheit "$tempCelsius") || currentTemp="--"
+            
+            currentHumidity=$(echo "$response" | jq -r '.current.relative_humidity_2m // "--"' 2>/dev/null)
+            [[ "$currentHumidity" == "null" ]] && currentHumidity="--"
+            
+            currentWindSpeed=$(echo "$response" | jq -r '.current.wind_speed_10m // "--"' 2>/dev/null)
+            if [[ "$currentWindSpeed" != "--" && "$currentWindSpeed" != "null" ]]; then
+                currentWindSpeedMph=$(kmh_to_mph "$currentWindSpeed")
+            else
+                currentWindSpeed="--"
+                currentWindSpeedMph="--"
+            fi
+            
+            local weatherCode=$(echo "$response" | jq -r '.current.weather_code // 0' 2>/dev/null)
+            [[ "$weatherCode" == "null" ]] && weatherCode=0
+            currentConditions="${weatherCodes[$weatherCode]:-Unknown}"
+            
+            # Check for severe weather and play alert if needed
+            if in_array "$weatherCode" "${severeWeatherCodes[@]}"; then
+                if [ "$severeWeatherAlerted" -eq 0 ]; then
+                    play_severe_weather_alert
+                    severeWeatherAlerted=1
+                fi
+            else
+                # Reset alert flag if weather is no longer severe
+                severeWeatherAlerted=0
+            fi
+            
+            # Process forecast data (limited to 3 days)
+            if [[ $(echo "$response" | jq -e '.daily' 2>/dev/null) ]]; then
+                for i in {0..2}; do
+                    # Process forecast data
+                    forecastDates[$i]=$(echo "$response" | jq -r ".daily.time[$i] // \"--\"" 2>/dev/null)
+                    [[ "${forecastDates[$i]}" != "--" && "${forecastDates[$i]}" != "null" ]] && \
+                        forecastFormattedDates[$i]=$(format_date "${forecastDates[$i]}") || forecastFormattedDates[$i]="--"
+                    
+                    local minTempC=$(echo "$response" | jq -r ".daily.temperature_2m_min[$i] // \"--\"" 2>/dev/null)
+                    [[ "$minTempC" != "--" && "$minTempC" != "null" ]] && \
+                        forecastMinTemps[$i]=$(celsius_to_fahrenheit "$minTempC") || forecastMinTemps[$i]="--"
+                    
+                    local maxTempC=$(echo "$response" | jq -r ".daily.temperature_2m_max[$i] // \"--\"" 2>/dev/null)
+                    [[ "$maxTempC" != "--" && "$maxTempC" != "null" ]] && \
+                        forecastMaxTemps[$i]=$(celsius_to_fahrenheit "$maxTempC") || forecastMaxTemps[$i]="--"
+                    
+                    local code=$(echo "$response" | jq -r ".daily.weather_code[$i] // 0" 2>/dev/null)
+                    [[ "$code" == "null" ]] && code=0
+                    forecastConditions[$i]="${weatherCodes[$code]:-Unknown}"
+                done
+            fi
+            
+            # Update timestamp
+            weatherLastUpdate=$(date +%s)
+            save_config
+        else
+            echo "Failed to fetch weather data. Response code: $?"
+            if [[ -n "$response" ]]; then
+                echo "First 100 chars of response: ${response:0:100}"
+            fi
+        fi
+    fi
+}
+
+# Function to change location (for settings)
+change_location() {
+    local newLocation="$1"
+    
+    if [[ -n "$newLocation" && "$newLocation" != "$cityName" ]]; then
+        # Try to parse the location using curl to a geocoding service
+        local result=$(curl -s --connect-timeout 10 "https://nominatim.openstreetmap.org/search?q=$newLocation&format=json" 2>/dev/null)
+        
+        if [[ -n "$result" && $(echo "$result" | jq -e '.[0]') ]]; then
+            cityName="$newLocation"
+            latitude=$(echo "$result" | jq -r '.[0].lat // "0.0"')
+            longitude=$(echo "$result" | jq -r '.[0].lon // "0.0"')
+            
+            # Force weather update
+            weatherLastUpdate=0
+            save_config
+            return 0
+        else
+            yad --title "Location Error" --text="Could not find location: $newLocation" --button=gtk-ok
+            return 1
+        fi
+    fi
+    return 1
+}
+
+# Display weather information in a text-info dialog
+display_weather() {
+    local lastUpdateText="Never updated"
+    [[ "$weatherLastUpdate" -gt 0 ]] && lastUpdateText="Last updated: $(time_diff "$weatherLastUpdate")"
+    
+    # Create the weather information text with proper line breaks
+    weatherInfoText="Weather for $cityName
+$lastUpdateText
+
+Current Conditions
+Temperature: ${currentTemp}° F
+Conditions: $currentConditions
+Humidity: ${currentHumidity}%
+Wind Speed: ${currentWindSpeedMph} mph
+
+3-Day Forecast
+────────────────────────────────────
+${forecastFormattedDates[0]}
+Temp: ${forecastMinTemps[0]}° to ${forecastMaxTemps[0]}° F
+Conditions: ${forecastConditions[0]}
+────────────────────────────────────
+${forecastFormattedDates[1]}
+Temp: ${forecastMinTemps[1]}° to ${forecastMaxTemps[1]}° F
+Conditions: ${forecastConditions[1]}
+────────────────────────────────────
+${forecastFormattedDates[2]}
+Temp: ${forecastMinTemps[2]}° to ${forecastMaxTemps[2]}° F
+Conditions: ${forecastConditions[2]}
+
+End of text. Press Control+Home to return to the beginning."
+
+    # Display in text-info dialog for screen reader accessibility
+    echo "$weatherInfoText" | yad --pname=I38Weather \
+        --title="I38 Weather Monitor" \
+        --text-info \
+        --show-cursor \
+        --width=500 \
+        --height=600 \
+        --center \
+        --button="Settings:$settingsBtn" \
+        --button="Refresh:$refreshBtn" \
+        --button="Close:$quitBtn"
+    
+    return $?
+}
+
+# Function to display settings dialog
+display_settings() {
+    local ret=$(yad --pname=I38WeatherSettings \
+        --title="I38 Weather Settings" \
+        --form \
+        --width=400 \
+        --center \
+        --field="Location:":TEXT "$cityName" \
+        --field="Current Coordinates:":LBL "Lat: $latitude, Lon: $longitude" \
+        --field="Temperature Unit:":CB "F!C" \
+        --field="Update Interval (minutes):":NUM "$updateInterval!5..120!5" \
+        --button="Cancel:1" \
+        --button="Save:0")
+    
+    local saveResult=$?
+    
+    if [[ $saveResult -eq 0 && -n "$ret" ]]; then
+        local newLocation=$(echo "$ret" | cut -d"|" -f1)
+        local newUnit=$(echo "$ret" | cut -d"|" -f3)
+        local newInterval=$(echo "$ret" | cut -d"|" -f4)
+        
+        # Apply any changes
+        [[ -n "$newLocation" && "$newLocation" != "$cityName" ]] && change_location "$newLocation"
+        [[ -n "$newUnit" && "$newUnit" != "$tempUnit" ]] && tempUnit="$newUnit" && save_config
+        [[ -n "$newInterval" && "$newInterval" != "$updateInterval" ]] && updateInterval="$newInterval" && save_config
+    fi
+}
+
+# Main loop
+while : ; do
+    get_location
+    fetch_weather_data
+    
+    # Display weather using the text-info widget
+    display_weather
+    ret=$?
+    
+    # Handle button actions
+    case $ret in
+        $refreshBtn)
+            # Force a weather update
+            weatherLastUpdate=0
+            continue
+            ;;
+        $settingsBtn)
+            # Display settings dialog
+            display_settings
+            continue
+            ;;
+        $quitBtn|252)
+            # Quit button or window closed
+            break
+            ;;
+    esac
+done
+
+exit 0