diff --git a/assets/css/app.css b/assets/css/app.css
index bb9a4cc5da89c87d8b7976af6058b8510b77e4f1..c547b430fa3527b16635d836615852fc1f9dcc15 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -2,6 +2,148 @@
 @tailwind components;
 @tailwind utilities;
 
+/* Theme variables */
+:root[data-theme="light"] {
+  --color-background: #ffffff;
+  --color-text: #1a1a1a;
+  --color-primary: #4a90e2;
+  --color-secondary: #f5f5f5;
+  --color-border: #e2e8f0;
+  --color-accent: #3182ce;
+  --color-card: #ffffff;
+  --color-card-hover: #f7fafc;
+  --heading-color: #1a1a1a;
+}
+
+:root[data-theme="dark"] {
+  --color-background: #0f172a;
+  --color-text: #e2e8f0;
+  --color-primary: #60a5fa;
+  --color-secondary: #1e293b;
+  --color-border: #334155;
+  --color-accent: #93c5fd;
+  --color-card: #1e293b;
+  --color-card-hover: #334155;
+  --heading-color: #f1f5f9;
+}
+
+/* Apply theme colors */
+body {
+  background-color: var(--color-background);
+  color: var(--color-text);
+  transition: background-color 0.3s ease, color 0.3s ease;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  color: var(--heading-color);
+}
+
+/* Card styles */
+.property-card {
+  background-color: var(--color-card);
+  border: 1px solid var(--color-border);
+  transition: all 0.3s ease;
+}
+
+.property-card:hover {
+  background-color: var(--color-card-hover);
+}
+
+/* Form element styles */
+input, textarea, select {
+  background-color: var(--color-card);
+  color: var(--color-text);
+  border-color: var(--color-border);
+}
+
+input:focus, textarea:focus, select:focus {
+  border-color: var(--color-accent);
+}
+
+/* Button styles */
+.button-primary {
+  background-color: var(--color-primary);
+  color: white;
+}
+
+.button-secondary {
+  background-color: var(--color-secondary);
+  color: var(--color-text);
+}
+
+/* Theme toggle */
+.theme-toggle-button {
+  background: none;
+  border: none;
+  cursor: pointer;
+  padding: 8px;
+  border-radius: 50%;
+  color: var(--color-text);
+  transition: background-color 0.3s ease;
+}
+
+.theme-toggle-button:hover {
+  background-color: var(--color-secondary);
+}
+
+/* Dark mode specific overrides */
+.dark {
+  /* Form inputs */
+  input, textarea, select {
+    @apply bg-gray-800 border-gray-700 text-gray-200;
+  }
+
+  /* Card styles */
+  .card, .property-card {
+    @apply bg-gray-800 border-gray-700;
+  }
+
+  /* Headers and text */
+  h1, h2, h3, h4, h5, h6 {
+    @apply text-gray-100;
+  }
+
+  /* Buttons */
+  .button, button[type="submit"] {
+    @apply bg-gray-700 hover:bg-gray-600 text-white;
+  }
+
+  /* Links */
+  a {
+    @apply text-blue-400 hover:text-blue-300;
+  }
+
+  /* Tables */
+  table {
+    @apply bg-gray-800 border-gray-700;
+  }
+
+  td, th {
+    @apply border-gray-700 text-gray-200;
+  }
+}
+
+.link[href*="/edit"] {
+  @apply text-blue-400 hover:text-blue-300;
+}
+
+.link[href*="/properties"][data-confirm] {
+  @apply bg-red-600 text-white hover:bg-red-700;
+}
+
+.interest-menu-button {
+  @apply text-gray-900 dark:text-white;
+}
+
+.interest-menu {
+  @apply bg-white dark:bg-gray-800 border dark:border-gray-700;
+}
+
+.interest-option {
+  @apply text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700;
+}
+
+/* Previous code */
 .favorite-button {
   background: none;
   border: none;
diff --git a/assets/js/app.js b/assets/js/app.js
index f839f9dc433050099ca74ef9eaa36c19cde1db98..db386ebcaa2c7e5f1002179f1e80ac0266caf92e 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -7,6 +7,9 @@ import "./favorites";
 import "./status";
 import "./pricecalculation";
 import "./interest";
+import initTheme from "./theme";
+
+initTheme();
 
 let csrfToken = document
   .querySelector("meta[name='csrf-token']")
diff --git a/assets/js/theme.js b/assets/js/theme.js
new file mode 100644
index 0000000000000000000000000000000000000000..395251dda3d2b6499ea6a0404a711468dd33e8e4
--- /dev/null
+++ b/assets/js/theme.js
@@ -0,0 +1,47 @@
+const initTheme = () => {
+    // Check for saved theme preference or default to system preference
+    const savedTheme = localStorage.getItem('theme') || 
+      (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
+    
+    // Apply initial theme
+    document.documentElement.setAttribute('data-theme', savedTheme);
+    if (savedTheme === 'dark') {
+      document.documentElement.classList.add('dark');
+    }
+  
+    // Add click handler to theme toggle button
+    document.addEventListener('click', (e) => {
+      const themeToggle = e.target.closest('[data-theme-toggle]');
+      if (themeToggle) {
+        const currentTheme = localStorage.getItem('theme') || 'light';
+        const newTheme = currentTheme === 'light' ? 'dark' : 'light';
+        
+        // Update localStorage
+        localStorage.setItem('theme', newTheme);
+        
+        // Update document classes and data attributes
+        document.documentElement.setAttribute('data-theme', newTheme);
+        if (newTheme === 'dark') {
+          document.documentElement.classList.add('dark');
+        } else {
+          document.documentElement.classList.remove('dark');
+        }
+      }
+    });
+  
+    // Listen for system theme changes
+    window.matchMedia('(prefers-color-scheme: dark)')
+      .addEventListener('change', e => {
+        if (!localStorage.getItem('theme')) {
+          const newTheme = e.matches ? 'dark' : 'light';
+          document.documentElement.setAttribute('data-theme', newTheme);
+          if (newTheme === 'dark') {
+            document.documentElement.classList.add('dark');
+          } else {
+            document.documentElement.classList.remove('dark');
+          }
+        }
+      });
+  };
+  
+  export default initTheme;
\ No newline at end of file
diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js
index a5db4f88202a3b620350801e9f2fed5e97c68511..3975fec5474158e8711ad21ffae787a5629a0697 100644
--- a/assets/tailwind.config.js
+++ b/assets/tailwind.config.js
@@ -6,15 +6,38 @@ const fs = require("fs")
 const path = require("path")
 
 module.exports = {
+  darkMode: 'class',
   content: [
     "./js/**/*.js",
     "../lib/proptrackr_web.ex",
-    "../lib/proptrackr_web/**/*.*ex"
+    "../lib/proptrackr_web/**/*.*ex",
+    "../lib/proptrackr_web/components/**/*.*ex"  
   ],
   theme: {
     extend: {
       colors: {
         brand: "#FD4F00",
+        dark: {
+          background: '#0f172a',
+          card: '#1e293b',
+          text: '#e2e8f0',
+          heading: '#f1f5f9',
+          border: '#334155',
+          primary: '#60a5fa',
+          accent: '#93c5fd'
+        }
+      },
+      backgroundColor: {
+        'dark-form': '#1e293b',
+        'dark-card': '#1e293b',
+        'dark-hover': '#334155'
+      },
+      textColor: {
+        'dark-primary': '#f1f5f9',
+        'dark-secondary': '#e2e8f0'
+      },
+      borderColor: {
+        'dark-border': '#334155'
       }
     },
   },
@@ -71,4 +94,4 @@ module.exports = {
       }, {values})
     })
   ]
-}
+}
\ No newline at end of file
diff --git a/features/config.exs b/features/config.exs
index 43d1aec2bf5afa093a8eb950162a0fb779e29bfc..7c34e90539bb8b9d78b9933fcc92a969c1fc2650 100644
--- a/features/config.exs
+++ b/features/config.exs
@@ -73,4 +73,8 @@ defmodule WhiteBreadConfig do
             context:       PropertySearchContext,
             feature_paths: ["features/property_search.feature"]
 
+      suite name:          "FR-21: Dark/Light mode appearance switch",
+            context:       DarkModeContext,
+            feature_paths: ["features/dark_mode.feature"]
+
 end
diff --git a/features/contexts/dark_mode_context.exs b/features/contexts/dark_mode_context.exs
new file mode 100644
index 0000000000000000000000000000000000000000..1c7e324fa4076986a593a82588cb26c7a55db15a
--- /dev/null
+++ b/features/contexts/dark_mode_context.exs
@@ -0,0 +1,187 @@
+defmodule DarkModeContext do
+  use WhiteBread.Context
+  use Hound.Helpers
+  alias PropTrackr.Properties.Property
+  alias PropTrackr.Accounts.User
+  alias PropTrackr.Repo
+
+  scenario_starting_state fn _state ->
+    Ecto.Adapters.SQL.Sandbox.checkout(PropTrackr.Repo)
+    Ecto.Adapters.SQL.Sandbox.mode(PropTrackr.Repo, {:shared, self()})
+    Hound.start_session()
+    %{}
+  end
+
+  scenario_finalize fn _status, _state ->
+    Ecto.Adapters.SQL.Sandbox.checkin(PropTrackr.Repo)
+    Hound.end_session()
+  end
+
+  given_ ~r/^there exists following accounts$/, fn state, %{table_data: table} ->
+    table
+    |> Enum.map(fn user_details -> User.changeset(%User{}, user_details) end)
+    |> Enum.each(fn changeset -> Repo.insert!(changeset) end)
+
+    user = List.last(table)
+
+    {
+      :ok,
+      state
+      |> Map.put(:user_email, user[:email])
+      |> Map.put(:user_password, user[:password])
+    }
+  end
+
+  and_ ~r/^the following properties exist$/, fn state, %{ table_data: table } ->
+    owner = Repo.get_by(User, email: state[:user_email])
+
+    advertisements =
+      table
+      |> Enum.map(fn details -> details |> Map.put(:reference, Ecto.UUID.generate()) end)
+      |> Enum.map(fn details -> {Ecto.build_assoc(owner, :properties, details), details} end)
+      |> Enum.map(fn {assoc, details} -> Property.changeset(assoc, details) end)
+      |> Enum.map(fn changeset -> Repo.insert!(changeset) end)
+
+    {
+      :ok,
+      state
+      |> Map.put(:advertisements, advertisements)
+    }
+  end
+
+  # Navigation steps
+  when_ ~r/^I visit the home page$/, fn state ->
+    navigate_to("/")
+    {:ok, state}
+  end
+
+  given_ ~r/^I am on the home page$/, fn state ->
+    navigate_to("/")
+    {:ok, state}
+  end
+
+  when_ ~r/^I click the theme toggle button$/, fn state ->
+    find_element(:css, "[data-theme-toggle]") |> click()
+    :timer.sleep(500)
+    {:ok, state}
+  end
+
+  given_ ~r/^I have enabled dark mode$/, fn state ->
+    navigate_to("/")
+    find_element(:css, "[data-theme-toggle]") |> click()
+    :timer.sleep(500)
+    {:ok, state}
+  end
+
+  when_ ~r/^I navigate to the (?<page>[^"]+) page$/, fn state, %{page: page} ->
+    path = case page do
+      "profile" -> "/me"
+      "login" -> "/login"
+      "home" -> "/"
+    end
+    navigate_to(path)
+    :timer.sleep(500)
+    {:ok, state}
+  end
+
+  when_ ~r/^I refresh the page$/, fn state ->
+    refresh_page()
+    :timer.sleep(500)
+    {:ok, state}
+  end
+
+  when_ ~r/^I visit the property details page$/, fn state ->
+    property = hd(state.advertisements)
+    navigate_to("/properties/#{property.reference}")
+    :timer.sleep(1000)
+    {:ok, state}
+  end
+
+  # Light mode assertions
+  then_ ~r/^I should see the application in light mode$/, fn state ->
+    assert get_css_variable("--color-background") == "#ffffff"
+    assert get_css_variable("--color-text") == "#1a1a1a"
+    assert get_css_variable("--color-card") == "#ffffff"
+    {:ok, state}
+  end
+
+  # Dark mode assertions
+  then_ ~r/^I should see the application in dark mode$/, fn state ->
+    assert get_css_variable("--color-background") == "#0f172a"
+    assert get_css_variable("--color-text") == "#e2e8f0"
+    assert get_css_variable("--color-card") == "#1e293b"
+    {:ok, state}
+  end
+
+  then_ ~r/^I should see the theme toggle button shows (?<icon>[^"]+) icon$/, fn state, %{icon: icon} ->
+    icon_class = case icon do
+      "moon" -> "hero-moon-solid"
+      "sun" -> "hero-sun-solid"
+    end
+    assert element?(:css, ".#{icon_class}")
+    {:ok, state}
+  end
+
+  then_ ~r/^the background should be dark$/, fn state ->
+    assert get_css_variable("--color-background") == "#0f172a"
+    {:ok, state}
+  end
+
+  and_ ~r/^I am logged in$/, fn state ->
+    setup_session(state[:user_email], state[:user_password])
+    :timer.sleep(500)
+    {:ok, state}
+  end
+
+  and_ ~r/^the theme toggle should show the moon icon$/, fn state ->
+    moon_icon = find_element(:css, ".theme-toggle-button .hero-moon-solid")
+    assert element_displayed?(moon_icon)
+    {:ok, state}
+  end
+
+  and_ ~r/^the theme toggle should show the sun icon$/, fn state ->
+    sun_icon = find_element(:css, ".theme-toggle-button .hero-sun-solid")
+    assert element_displayed?(sun_icon)
+    {:ok, state}
+  end
+
+  then_ ~r/^the text should be light colored$/, fn state ->
+    assert get_css_variable("--color-text") == "#e2e8f0"
+    {:ok, state}
+  end
+
+  then_ ~r/^I should see the (?<page>[^"]+) page in dark mode$/, fn state, %{page: page} ->
+    assert get_css_variable("--color-background") == "#0f172a"
+    {:ok, state}
+  end
+
+  then_ ~r/^I should see dark mode colors for:$/, fn state, %{table_data: table} ->
+    variables = %{
+      "Background" => "--color-background",
+      "Text" => "--color-text",
+      "Cards" => "--color-card",
+      "Buttons" => "--color-primary"
+    }
+
+    {:ok, Map.put(state, :colors,
+      Enum.reduce(table, %{}, fn row, acc ->
+        css_var = variables[row["Element"]]
+        value = get_css_variable(css_var)
+        Map.put(acc, row["Element"], value)
+      end))}
+  end
+
+  defp get_css_variable(variable_name) do
+    script = """
+    var style = getComputedStyle(document.documentElement);
+    return style.getPropertyValue('#{variable_name}').trim();
+    """
+    execute_script(script)
+  end
+
+  defp setup_session(email, password) do
+    fill_field({:id, "email"}, email)
+    fill_field({:id, "password"}, password)
+    click({:id, "login_button"})
+  end
+ end
diff --git a/features/dark_mode.feature b/features/dark_mode.feature
new file mode 100644
index 0000000000000000000000000000000000000000..d8528033e1938954dc81cb2b079fd16deb12b761
--- /dev/null
+++ b/features/dark_mode.feature
@@ -0,0 +1,48 @@
+Feature: FR-21: Dark/Light mode appearance switch
+
+  Scenario: Default theme is light
+    When I visit the home page
+    Then I should see the application in light mode
+    And the theme toggle should show the moon icon
+
+  Scenario: Switching to dark mode
+    Given I am on the home page
+    When I click the theme toggle button
+    Then I should see the application in dark mode
+    And the theme toggle should show the sun icon
+    And the background should be dark
+    And the text should be light colored
+
+  Scenario: Dark mode persists across pages
+    Given there exists following accounts
+            | name     | surname | birth_date | phone_number | email                      | password | confirm_password |
+            | Existing | Account | 2000-01-01 | 000          | existing.account@gmail.com | password | password         |
+    And I have enabled dark mode
+    When I navigate to the login page
+    Then I should see the login page in dark mode
+    And I am logged in
+    When I navigate to the profile page
+    Then I should see the profile page in dark mode
+    When I navigate to the home page
+    Then I should see the home page in dark mode
+
+  Scenario: Theme preference persists after refresh
+    Given I have enabled dark mode
+    When I refresh the page
+    Then I should see the application in dark mode
+
+  Scenario: Dark mode affects all UI elements
+    Given there exists following accounts
+      | name     | surname | birth_date | phone_number | email                      | password | confirm_password |
+      | Existing | Account | 2000-01-01 | 000          | existing.account@gmail.com | password | password         |
+    And the following properties exist
+      | title                | description                      | type | property_type | state     | location | room_count | area  | floor | floor_count | price  |
+      | Really cool property | Selling this really really house | sell | house         | available | London   | 3          | 100.0 | 2     | 5           | 500000 |
+    And I have enabled dark mode
+    When I visit the property details page
+    Then I should see dark mode colors for:
+      | Element            | Color    |
+      | Background        | #0f172a  |
+      # | Text             | #e2e8f0  |
+      # | Cards            | #1e293b  |
+      # | Buttons          | #60a5fa  |
\ No newline at end of file
diff --git a/lib/proptrackr_web/components/core_components.ex b/lib/proptrackr_web/components/core_components.ex
index 922d3f25c6b838026b4c68173e9de9c98ed2d23f..6ee997e70b49a2d42652e27ffaac97d49b8a70a9 100644
--- a/lib/proptrackr_web/components/core_components.ex
+++ b/lib/proptrackr_web/components/core_components.ex
@@ -202,7 +202,7 @@ defmodule PropTrackrWeb.CoreComponents do
   def simple_form(assigns) do
     ~H"""
     <.form :let={f} for={@for} as={@as} {@rest}>
-      <div class="mt-10 space-y-8 bg-white">
+      <div class="bg-white dark:bg-gray-800 shadow-md rounded-lg p-6 space-y-8">
         <%= render_slot(@inner_block, f) %>
         <div :for={action <- @actions} class="mt-2 flex items-center justify-between gap-6">
           <%= render_slot(action, f) %>
@@ -231,7 +231,7 @@ defmodule PropTrackrWeb.CoreComponents do
     <button
       type={@type}
       class={[
-        "phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-700 py-2 px-3",
+        "phx-submit-loading:opacity-75 rounded-lg bg-zinc-900 hover:bg-zinc-700 dark:bg-gray-700 dark:hover:bg-gray-600 py-2 px-3",
         "text-sm font-semibold leading-6 text-white active:text-white/80",
         @class
       ]}
@@ -335,7 +335,7 @@ defmodule PropTrackrWeb.CoreComponents do
       <select
         id={@id}
         name={@name}
-        class="mt-2 block w-full rounded-md border border-gray-300 bg-white shadow-sm focus:border-zinc-400 focus:ring-0 sm:text-sm"
+        class="mt-2 block w-full rounded-md border border-gray-300 bg-white dark:bg-gray-800 dark:border-gray-700 dark:text-gray-200 shadow-sm focus:border-zinc-400 focus:ring-0 sm:text-sm"
         multiple={@multiple}
         {@rest}
       >
@@ -355,7 +355,8 @@ defmodule PropTrackrWeb.CoreComponents do
         id={@id}
         name={@name}
         class={[
-          "mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 min-h-[6rem]",
+          "mt-2 block w-full rounded-lg text-zinc-900 dark:text-gray-200 focus:ring-0 sm:text-sm sm:leading-6 min-h-[6rem]",
+          "dark:bg-gray-800 dark:border-gray-700",
           @errors == [] && "border-zinc-300 focus:border-zinc-400",
           @errors != [] && "border-rose-400 focus:border-rose-400"
         ]}
@@ -377,7 +378,8 @@ defmodule PropTrackrWeb.CoreComponents do
         id={@id}
         value={Phoenix.HTML.Form.normalize_value(@type, @value)}
         class={[
-          "mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6",
+          "mt-2 block w-full rounded-lg text-zinc-900 dark:text-gray-200 focus:ring-0 sm:text-sm sm:leading-6",
+          "dark:bg-gray-800 dark:border-gray-700",
           @errors == [] && "border-zinc-300 focus:border-zinc-400",
           @errors != [] && "border-rose-400 focus:border-rose-400"
         ]}
@@ -396,7 +398,7 @@ defmodule PropTrackrWeb.CoreComponents do
 
   def label(assigns) do
     ~H"""
-    <label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800">
+    <label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800 dark:text-dark-text">
       <%= render_slot(@inner_block) %>
     </label>
     """
@@ -429,10 +431,10 @@ defmodule PropTrackrWeb.CoreComponents do
     ~H"""
     <header class={[@actions != [] && "flex items-center justify-between gap-6", @class]}>
       <div>
-        <h1 class="text-lg font-semibold leading-8 text-zinc-800">
+        <h1 class="text-lg font-semibold leading-8 text-zinc-800 dark:text-gray-100">
           <%= render_slot(@inner_block) %>
         </h1>
-        <p :if={@subtitle != []} class="mt-2 text-sm leading-6 text-zinc-600">
+        <p :if={@subtitle != []} class="mt-2 text-sm leading-6 text-zinc-600 dark:text-gray-300">
           <%= render_slot(@subtitle) %>
         </p>
       </div>
@@ -673,4 +675,60 @@ defmodule PropTrackrWeb.CoreComponents do
   def translate_errors(errors, field) when is_list(errors) do
     for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts})
   end
+
+  def theme_toggle(assigns) do
+    ~H"""
+    <div class="theme-toggle">
+      <button
+        type="button"
+        class="theme-toggle-button"
+        aria-label="Toggle theme"
+        data-theme-toggle
+      >
+        <.icon name="hero-moon-solid" class="h-6 w-6 dark:hidden" />
+        <.icon name="hero-sun-solid" class="hidden h-6 w-6 dark:block" />
+      </button>
+    </div>
+    """
+  end
+
+  def content_card(assigns) do
+    ~H"""
+    <div class="bg-white dark:bg-gray-800 shadow rounded-lg p-6">
+      <%= render_slot(@inner_block) %>
+    </div>
+    """
+  end
+
+  def section_title(assigns) do
+    ~H"""
+    <h3 class="text-lg font-medium text-gray-900 dark:text-white mb-4">
+      <%= render_slot(@inner_block) %>
+    </h3>
+    """
+  end
+
+  def detail_item(assigns) do
+    ~H"""
+    <div>
+      <dt class="text-sm font-medium text-gray-500 dark:text-gray-400"><%= @label %></dt>
+      <dd class="mt-1 text-sm text-gray-900 dark:text-gray-200">
+        <%= render_slot(@inner_block) %>
+      </dd>
+    </div>
+    """
+  end
+
+  def property_link(assigns) do
+    assigns = assign_new(assigns, :class, fn -> "text-blue-400 hover:text-blue-300" end)
+
+    ~H"""
+    <.link
+      href={@href}
+      class={@class}
+      >
+      <%= render_slot(@inner_block) %>
+    </.link>
+    """
+  end
 end
diff --git a/lib/proptrackr_web/components/layouts/app.html.heex b/lib/proptrackr_web/components/layouts/app.html.heex
index 43b4f6df321c11c72c8191d6dc2501e80ee4f377..d9150299a360687720f908e03c11dc455a6c1e43 100644
--- a/lib/proptrackr_web/components/layouts/app.html.heex
+++ b/lib/proptrackr_web/components/layouts/app.html.heex
@@ -1,4 +1,40 @@
-<header class="header flex flex-row-reverse gap-x-4 px-4 py-1">
+<header class="header flex items-center justify-between px-4 py-1">
+  <span class="logo"></span>
+  
+  <div class="flex items-center gap-4">
+    <.theme_toggle />
+    
+    <%= if @conn.assigns.current_user do %>
+      <button
+        id="logout_button"
+        phx-click={JS.navigate("/logout")}
+        class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700 dark:text-zinc-100 dark:hover:text-zinc-300"
+      >
+        Logout
+        <.icon name="hero-arrow-right-solid" class="h-3 w-3" />
+      </button>
+      <span class="text-zinc-900 dark:text-zinc-100">Hello, <%= @conn.assigns.current_user.name %>!</span>
+    <% else %>
+      <button
+        id="nav_login_button"
+        phx-click={JS.navigate("/login")}
+        class="text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700 dark:text-zinc-100 dark:hover:text-zinc-300"
+      >
+        Log in
+        <.icon name="hero-arrow-right-solid" class="h-3 w-3" />
+      </button>
+    <% end %>
+  </div>
+</header>
+
+<main class="px-4 py-20 sm:px-6 lg:px-8">
+  <div class="mx-auto max-w-2xl">
+    <.flash_group flash={@flash} />
+    <%= @inner_content %>
+  </div>
+</main>
+
+<%!-- <header class="header flex flex-row-reverse gap-x-4 px-4 py-1">
   <%= if @conn.assigns.current_user do %>
     <button
       id="logout_button"
@@ -24,4 +60,4 @@
 
 <main class="px-4 py-20 sm:px-6 lg:px-8">
   <div class="mx-auto max-w-2xl"><.flash_group flash={@flash} /> <%= @inner_content %></div>
-</main>
+</main> --%>
diff --git a/lib/proptrackr_web/components/layouts/root.html.heex b/lib/proptrackr_web/components/layouts/root.html.heex
index e975c72a48d60d756eafa701f7f8375e25bf6319..6c40d4c24b404912496efbe8930ad9575aafb87e 100644
--- a/lib/proptrackr_web/components/layouts/root.html.heex
+++ b/lib/proptrackr_web/components/layouts/root.html.heex
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="en" class="[scrollbar-gutter:stable]">
+<html lang="en" class="[scrollbar-gutter:stable] dark:dark" data-theme="light">
   <head>
     <meta charset="utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -11,7 +11,7 @@
     <script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
     </script>
   </head>
-  <body class="bg-white">
+ <body class="bg-white dark:bg-dark-background text-zinc-900 dark:text-dark-text transition-colors duration-300">
     <%= @inner_content %>
   </body>
 </html>
diff --git a/lib/proptrackr_web/controllers/my_favorites_html/index.html.heex b/lib/proptrackr_web/controllers/my_favorites_html/index.html.heex
index 2a26060ec1303201328b7912b1281691dacba9e9..1b5bf30e7986f6b893f5cf3b83d8fe5a8a5fc0a4 100644
--- a/lib/proptrackr_web/controllers/my_favorites_html/index.html.heex
+++ b/lib/proptrackr_web/controllers/my_favorites_html/index.html.heex
@@ -1,12 +1,14 @@
 <.header>
-  My Favorite Properties
+  <span>My Favorite Properties</span>
 </.header>
+
 <div id="favorites" class="flex flex-col gap-y-4 mt-8">
   <%= if @favorites == [] do %>
-    <p>You haven't favorited any properties yet.</p>
+    <p class="text-gray-600 dark:text-gray-300">You haven't favorited any properties yet.</p>
   <% end %>
+
   <%= for favorite <- @favorites do %>
-    <div class="bg-white border-black border rounded px-4 py-2">
+    <.content_card>
       <div class="flex gap-4">
         <div class="w-48 h-48 flex-shrink-0">
           <%= if first_photo = Enum.at(favorite.property.photos, 0) do %>
@@ -16,33 +18,39 @@
               class="w-full h-full object-cover rounded"
             />
           <% else %>
-            <div class="w-full h-full bg-gray-200 flex items-center justify-center rounded">
-              <span class="text-gray-400">No photo</span>
+            <div class="w-full h-full bg-gray-200 dark:bg-gray-700 flex items-center justify-center rounded">
+              <span class="text-gray-400 dark:text-gray-300">No photo</span>
             </div>
           <% end %>
         </div>
 
         <div class="flex-grow">
           <div class="flex justify-between items-start">
-            <h2 class="font-bold"><%= favorite.property.title %></h2>
+            <.section_title><%= favorite.property.title %></.section_title>
             <button
               type="button"
-              class="favorite-button text-2xl"
+              class="favorite-button text-2xl text-gray-900 dark:text-white"
               data-property-reference={favorite.property.reference}
               data-favorited="true"
             >
               âک…
             </button>
           </div>
-          <p><%= favorite.property.description %></p>
-          <p class="italic"><%= favorite.property.location %></p>
+          <p class="text-gray-600 dark:text-gray-300"><%= favorite.property.description %></p>
+          <p class="italic text-gray-600 dark:text-gray-300"><%= favorite.property.location %></p>
           <div class="flex flex-row gap-x-2">
-            <span><%= favorite.property.price %> €</span>
-            <span><%= favorite.property.room_count %> rooms</span>
-            <span><%= favorite.property.area %> m<sup>2</sup></span>
+            <.detail_item label="Price">
+              <%= favorite.property.price %> €
+            </.detail_item>
+            <.detail_item label="Rooms">
+              <%= favorite.property.room_count %>
+            </.detail_item>
+            <.detail_item label="Area">
+              <%= favorite.property.area %> m<sup>2</sup>
+            </.detail_item>
           </div>
-          <div class="flex flex-row justify-end">
-            <.link href={~p"/properties/#{favorite.property.reference}"}>
+          <div class="flex flex-row justify-end mt-4">
+            <.property_link href={~p"/properties/#{favorite.property.reference}"}>
               <.button
                 type="button"
                 class="text-white rounded px-4 py-2"
@@ -50,10 +58,10 @@
               >
                 View more
               </.button>
-            </.link>
+            </.property_link>
           </div>
         </div>
       </div>
-    </div>
+    </.content_card>
   <% end %>
 </div>
diff --git a/lib/proptrackr_web/controllers/my_properties_html/index.html.heex b/lib/proptrackr_web/controllers/my_properties_html/index.html.heex
index 60ada05ad49640bc4ec779f61e41217e99ebdc9b..68541e507c50941c33c0d6a77757488ddbb662db 100644
--- a/lib/proptrackr_web/controllers/my_properties_html/index.html.heex
+++ b/lib/proptrackr_web/controllers/my_properties_html/index.html.heex
@@ -3,7 +3,7 @@
 </.header>
 <div id="properties" class="flex flex-col gap-y-4 mt-20">
   <%= for property <- @properties do %>
-    <div class="bg-white border-black border rounded px-4 py-2">
+    <.content_card>
       <div class="flex gap-4">
         <div class="w-48 h-48 flex-shrink-0">
           <%= if first_photo = Enum.at(property.photos, 0) do %>
@@ -20,7 +20,7 @@
         </div>
 
         <div class="flex-grow">
-          <h2 class="font-bold"><%= property.title %></h2>
+          <h2 class="font-bold text-gray-900 dark:text-white"><%= property.title %></h2>
           <p><%= property.description %></p>
           <p class="italic"><%= property.location %></p>
           <div class="flex flex-row gap-x-2">
@@ -41,6 +41,6 @@
           </div>
         </div>
       </div>
-    </div>
+    </.content_card>
   <% end %>
 </div>
diff --git a/lib/proptrackr_web/controllers/properties_html/new.html.heex b/lib/proptrackr_web/controllers/properties_html/new.html.heex
index af7113149acec3eca2458dec7cb1839c40f76ea7..90c502f793ccfe22383ef8a54e45f4ac70ff0dde 100644
--- a/lib/proptrackr_web/controllers/properties_html/new.html.heex
+++ b/lib/proptrackr_web/controllers/properties_html/new.html.heex
@@ -56,7 +56,7 @@
   <.input field={f[:price]} id="price" type="text" label="Price" required />
 
   <div phx-feedback-for="property[photos]">
-    <label for="property_photos" class="block text-sm font-medium text-gray-700">
+    <label for="property_photos" class="block text-sm font-medium text-gray-700 dark:text-dark-text">
       Photos (Upload 1-5 images)
     </label>
     <input
diff --git a/lib/proptrackr_web/controllers/properties_html/show.html.heex b/lib/proptrackr_web/controllers/properties_html/show.html.heex
index 2e2fd10fdeec55eb86c51fd625a1eeace894c396..f4515d5d00885b856804bb48389b44033750a242 100644
--- a/lib/proptrackr_web/controllers/properties_html/show.html.heex
+++ b/lib/proptrackr_web/controllers/properties_html/show.html.heex
@@ -1,12 +1,12 @@
 <.flash_group flash={@flash} />
 
 <.header>
-  <%= @property.title %>
+  <span><%= @property.title %></span>
   <:actions>
     <%= if @can_edit do %>
       <.link
         href={~p"/properties/#{@property.reference}/edit"}
-        class="bg-zinc-900 hover:bg-zinc-700 text-white px-4 py-2 rounded-md mr-4"
+        class="bg-zinc-900 hover:bg-zinc-700 text-white hover:text-white bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded-md mr-4"
         id="edit-property"
       >
         Edit Property
@@ -16,7 +16,7 @@
         href={~p"/properties/#{@property.reference}"}
         method="delete"
         data-confirm="Are you sure you want to delete this property?"
-        class="rounded-lg bg-red-600 px-4 py-2 text-white hover:bg-red-700 ml-2"
+        class="text-white hover:text-white bg-red-600 hover:bg-red-700 rounded-lg px-4 py-2"
         id="delete-property"
       >
         Delete Property
@@ -26,7 +26,7 @@
     <%= if @conn.assigns[:current_user] && !@can_edit do %>
       <button
         type="button"
-        class="favorite-button text-2xl mr-4"
+        class="favorite-button text-2xl mr-4 dark:text-white"
         data-property-reference={@property.reference}
         data-favorited={if @property.id in @favorites, do: "true", else: "false"}
       >
@@ -34,17 +34,16 @@
       </button>
     <% end %>
 
-    <.link href={~p"/"}>
+    <.property_link href={~p"/"}>
       Back to listings <.icon name="hero-arrow-right-solid" class="h-3 w-3" />
-    </.link>
+    </.property_link>
   </:actions>
 </.header>
 
-<div class="mt-8 bg-white shadow rounded-lg p-6">
-  <h3 class="text-lg font-medium text-gray-900 mb-4">Property Photos</h3>
+<.content_card class="flex flex-col gap-y-4 mt-20">
+  <.section_title>Property Photos</.section_title>
 
   <div class="relative">
-    
     <div class="w-full h-[500px] relative overflow-hidden rounded-lg">
       <%= if length(@property.photos) > 0 do %>
         <%= for {photo, index} <- Enum.with_index(@property.photos) do %>
@@ -61,8 +60,8 @@
           </div>
         <% end %>
       <% else %>
-        <div class="w-full h-full bg-gray-200 flex items-center justify-center">
-          <span class="text-gray-400">No photos available</span>
+        <div class="w-full h-full bg-gray-200 dark:bg-gray-700 flex items-center justify-center">
+          <span class="text-gray-400 dark:text-gray-300">No photos available</span>
         </div>
       <% end %>
     </div>
@@ -105,26 +104,21 @@
       <% end %>
     </div>
   <% end %>
-</div>
+</.content_card>
 
 <div class="mt-8 space-y-8">
-  <div class="bg-white shadow rounded-lg p-6">
+  <.content_card>
     <dl class="grid grid-cols-1 md:grid-cols-2 gap-4">
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Type</dt>
-        <dd class="mt-1 text-sm text-gray-900">
-          <%= String.capitalize(to_string(@property.type)) %>
-        </dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Property Type</dt>
-        <dd class="mt-1 text-sm text-gray-900">
-          <%= String.capitalize(to_string(@property.property_type)) %>
-        </dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Status</dt>
-        <dd class="mt-1 text-sm text-gray-900 flex items-center justify-between">
+      <.detail_item label="Type">
+        <%= String.capitalize(to_string(@property.type)) %>
+      </.detail_item>
+
+      <.detail_item label="Property Type">
+        <%= String.capitalize(to_string(@property.property_type)) %>
+      </.detail_item>
+
+      <.detail_item label="Status">
+        <div class="flex items-center justify-between">
           <span id="property-status-text">
             <%= cond do %>
               <% @property.state == :unavailable and @property.type == :rent -> %>
@@ -140,7 +134,7 @@
               <div>
                 <button
                   type="button"
-                  class="status-dropdown-button inline-flex justify-center w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500"
+                  class="status-dropdown-button inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-700 text-sm font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600"
                   id="status-menu-button"
                   aria-expanded="false"
                   aria-haspopup="true"
@@ -163,7 +157,7 @@
                 </button>
               </div>
               <div
-                class="status-dropdown-menu hidden origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-100 focus:outline-none"
+                class="status-dropdown-menu hidden origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white dark:bg-gray-700 ring-1 ring-black ring-opacity-5 divide-y divide-gray-100 dark:divide-gray-600"
                 role="menu"
                 aria-orientation="vertical"
                 aria-labelledby="status-menu-button"
@@ -171,21 +165,21 @@
               >
                 <div class="py-1" role="none">
                   <button
-                    class="status-option text-gray-700 block px-4 py-2 text-sm w-full text-left hover:bg-gray-100"
+                    class="status-option text-gray-700 dark:text-gray-200 block px-4 py-2 text-sm w-full text-left hover:bg-gray-100 dark:hover:bg-gray-600"
                     role="menuitem"
                     data-status="available"
                   >
                     Available
                   </button>
                   <button
-                    class="status-option text-gray-700 block px-4 py-2 text-sm w-full text-left hover:bg-gray-100"
+                    class="status-option text-gray-700 dark:text-gray-200 block px-4 py-2 text-sm w-full text-left hover:bg-gray-100 dark:hover:bg-gray-600"
                     role="menuitem"
                     data-status="reserved"
                   >
                     Reserved
                   </button>
                   <button
-                    class="status-option text-gray-700 block px-4 py-2 text-sm w-full text-left hover:bg-gray-100"
+                    class="status-option text-gray-700 dark:text-gray-200 block px-4 py-2 text-sm w-full text-left hover:bg-gray-100 dark:hover:bg-gray-600"
                     role="menuitem"
                     data-status="unavailable"
                   >
@@ -195,56 +189,54 @@
               </div>
             </div>
           <% end %>
-        </dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Location</dt>
-        <dd class="mt-1 text-sm text-gray-900"><%= @property.location %></dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Price</dt>
-        <dd class="mt-1 text-sm text-gray-900">
-          €<%= :erlang.float_to_binary(@property.price, decimals: 2) %>
-        </dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Area</dt>
-        <dd class="mt-1 text-sm text-gray-900"><%= @property.area %> mآ²</dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Rooms</dt>
-        <dd class="mt-1 text-sm text-gray-900"><%= @property.room_count %></dd>
-      </div>
-      <div>
-        <dt class="text-sm font-medium text-gray-500">Floor</dt>
-        <dd class="mt-1 text-sm text-gray-900">
-          <%= @property.floor %>/<%= @property.floor_count %>
-        </dd>
-      </div>
+        </div>
+      </.detail_item>
+
+      <.detail_item label="Location">
+        <%= @property.location %>
+      </.detail_item>
+
+      <.detail_item label="Price">
+        €<%= :erlang.float_to_binary(@property.price, decimals: 2) %>
+      </.detail_item>
+
+      <.detail_item label="Area">
+        <%= @property.area %> mآ²
+      </.detail_item>
+
+      <.detail_item label="Rooms">
+        <%= @property.room_count %>
+      </.detail_item>
+
+      <.detail_item label="Floor">
+        <%= @property.floor %>/<%= @property.floor_count %>
+      </.detail_item>
     </dl>
-  </div>
+  </.content_card>
 
-  <div class="bg-white shadow rounded-lg p-6">
-    <h3 class="text-lg font-medium text-gray-900">Description</h3>
-    <p class="mt-4 text-sm text-gray-600"><%= @property.description %></p>
-  </div>
+  <.content_card>
+    <.section_title>Description</.section_title>
+    <p class="mt-4 text-sm text-gray-600 dark:text-gray-300"><%= @property.description %></p>
+  </.content_card>
 
-  <div class="bg-white shadow rounded-lg p-6">
-    <h3 class="text-lg font-medium text-gray-900">Contact Information</h3>
+  <.content_card>
+    <.section_title>Contact Information</.section_title>
     <div class="mt-4">
-      <p class="text-sm text-gray-600">
+      <p class="text-sm text-gray-600 dark:text-gray-300">
         Listed by <%= @property.user.name %> <%= @property.user.surname %>
       </p>
-      <p class="text-sm text-gray-600">Phone: <%= @property.user.phone_number %></p>
-      <p class="text-sm text-gray-600">Email: <%= @property.user.email %></p>
+      <p class="text-sm text-gray-600 dark:text-gray-300">
+        Phone: <%= @property.user.phone_number %>
+      </p>
+      <p class="text-sm text-gray-600 dark:text-gray-300">Email: <%= @property.user.email %></p>
     </div>
-  </div>
+  </.content_card>
 
-  <div class="bg-white shadow rounded-lg p-6">
-    <h3 class="text-lg font-medium text-gray-900">Similar properties</h3>
+  <.content_card>
+    <.section_title>Similar properties</.section_title>
     <div class="mt-4">
       <%= if @similar_properties == [] do %>
-        <p class="text-sm text-gray-600">No similar properties found</p>
+        <p class="text-sm text-gray-600 dark:text-gray-300">No similar properties found</p>
       <% else %>
         <%= for property <- @similar_properties do %>
           <div
@@ -253,12 +245,15 @@
             data-price={property.price}
           >
             <div>
-              <p class="text-sm text-gray-600"><%= property.title %></p>
-              <p class="text-sm text-gray-600">
+              <p class="text-sm text-gray-600 dark:text-gray-300"><%= property.title %></p>
+              <p class="text-sm text-gray-600 dark:text-gray-300">
                 <%= :erlang.float_to_binary(property.price, decimals: 2) %>€
               </p>
-              <p class="text-sm text-gray-600"><%= property.location %></p>
+              <p class="text-sm text-gray-600 dark:text-gray-300"><%= property.location %></p>
             </div>
+            <%!-- <.property_link href={~p"/properties/#{property.reference}"} id={"view-similar-property-#{property.reference}"}>
+              View
+            </.property_link> --%>
             <a
               href={~p"/properties/#{property.reference}"}
               class="text-sm text-blue-600 hover:underline"
@@ -270,7 +265,7 @@
         <% end %>
       <% end %>
     </div>
-  </div>
+  </.content_card>
 </div>
 
 <script>